Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 7feaecb

Browse files
committed
feat: add solutions to lc problem: No.0645. Set Mismatch
1 parent 545ee4e commit 7feaecb

File tree

6 files changed

+188
-134
lines changed

6 files changed

+188
-134
lines changed

‎README_EN.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
## Introduction
1616

17-
Complete solutions to [LeetCode](https://leetcode-cn.com/problemset/all/), [LCOF](https://leetcode-cn.com/problemset/lcof/) and [LCCI](https://leetcode-cn.com/problemset/lcci/) problems, updated daily. Please give me a [star](https://github.com/doocs/leetcode) 🌟 if you like it.
17+
Complete solutions to [LeetCode](https://leetcode.com/problemset/all/), [LCOF](https://leetcode-cn.com/problemset/lcof/) and [LCCI](https://leetcode-cn.com/problemset/lcci/) problems, updated daily. Please give me a [star](https://github.com/doocs/leetcode) 🌟 if you like it.
1818

1919
[中文文档](./README.md)
2020

‎solution/0600-0699/0645.Set Mismatch/README.md‎

Lines changed: 86 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,17 @@
3737
<li><code>1 <= nums[i] <= 10<sup>4</sup></code></li>
3838
</ul>
3939

40-
4140
## 解法
4241

4342
<!-- 这里可写通用的实现逻辑 -->
4443

45-
首先使用 1 到 n 的所有数字做异或运算,然后再与数组中的所有数字异或,得到的值就是缺失数字与重复的数字异或的结果。
44+
异或运算求解。
45+
46+
首先明确,两个相同的数异或之后的结果为 0。对该数组所有元素以及 `i∈[1, n]` 所有数字进行异或运算,结果就是**两个只出现一次的数字异或的结果**,即 `eor = a ^ b`
4647

47-
接着计算中这个值中其中一个非零的位 pos。然后 pos 位是否为 1,将 nums 数组的元素分成两部分,分别异或;接着将 `1~n` 的元素也分成两部分,分别异或。得到的两部分结果分别为 a,b,即是缺失数字与重复数字
48+
找出这个结果 eor 中最后一个二进制位为 1 而其余位为 0 的数,即 `eor & (~eor + 1)`,之后遍历数组所有元素以及 `i∈[1, n]` 所有数字,二进制位为 0 的元素异或到 a
4849

49-
最后判断数组中是否存在 a 或 b,若存在 a,说明重复数字是 a,返回 `[a,b]`,否则返回 `[b,a]`
50+
遍历结束后 `b = eor ^ a`,返回结果即可
5051

5152
<!-- tabs:start -->
5253

@@ -57,28 +58,19 @@
5758
```python
5859
class Solution:
5960
def findErrorNums(self, nums: List[int]) -> List[int]:
60-
res = 0
61-
for num in nums:
62-
res ^= num
63-
for i in range(1, len(nums) + 1):
64-
res ^= i
65-
pos = 0
66-
while (res & 1) == 0:
67-
res >>= 1
68-
pos += 1
69-
a = b = 0
70-
for num in nums:
71-
if ((num >> pos) & 1) == 0:
72-
a ^= num
73-
else:
74-
b ^= num
75-
for i in range(1, len(nums) + 1):
76-
if ((i >> pos) & 1) == 0:
61+
eor, n = 0, len(nums)
62+
for i in range(1, n + 1):
63+
eor ^= (i ^ nums[i - 1])
64+
diff = eor & (~eor + 1)
65+
a = 0
66+
for i in range(1, n + 1):
67+
if (nums[i - 1] & diff) == 0:
68+
a ^= nums[i - 1]
69+
if (i & diff) == 0:
7770
a ^= i
78-
else:
79-
b ^= i
71+
b = eor ^ a
8072
for num in nums:
81-
if num == a:
73+
if a == num:
8274
return [a, b]
8375
return [b, a]
8476
```
@@ -90,35 +82,23 @@ class Solution:
9082
```java
9183
class Solution {
9284
public int[] findErrorNums(int[] nums) {
93-
int res = 0;
94-
for (int num :nums) {
95-
res ^= num;
85+
int eor = 0;
86+
for (int i =1; i <=nums.length; ++i) {
87+
eor ^= (i ^ nums[i -1]);
9688
}
97-
for (int i = 1, n = nums.length; i < n + 1; ++i) {
98-
res ^= i;
99-
}
100-
int pos = 0;
101-
while ((res & 1) == 0) {
102-
res >>= 1;
103-
++pos;
104-
}
105-
int a = 0, b = 0;
106-
for (int num : nums) {
107-
if (((num >> pos) & 1) == 0) {
108-
a ^= num;
109-
} else {
110-
b ^= num;
89+
int diff = eor & (~eor + 1);
90+
int a = 0;
91+
for (int i = 1; i <= nums.length; ++i) {
92+
if ((nums[i - 1] & diff) == 0) {
93+
a ^= nums[i - 1];
11194
}
112-
}
113-
for (int i = 1, n = nums.length; i < n + 1; ++i) {
114-
if (((i >> pos) & 1) == 0) {
95+
if ((i & diff) == 0) {
11596
a ^= i;
116-
} else {
117-
b ^= i;
11897
}
11998
}
99+
int b = eor ^ a;
120100
for (int num : nums) {
121-
if (num == a) {
101+
if (a == num) {
122102
return new int[]{a, b};
123103
}
124104
}
@@ -127,6 +107,37 @@ class Solution {
127107
}
128108
```
129109

110+
### **C++**
111+
112+
```cpp
113+
class Solution {
114+
public:
115+
vector<int> findErrorNums(vector<int>& nums) {
116+
int eor = 0, n = nums.size();
117+
for (int i = 1; i <= n; ++i) {
118+
eor ^= (i ^ nums[i - 1]);
119+
}
120+
int diff = eor & (~eor + 1);
121+
int a = 0;
122+
for (int i = 1; i <= n; ++i) {
123+
if ((nums[i - 1] & diff) == 0) {
124+
a ^= nums[i - 1];
125+
}
126+
if ((i & diff) == 0) {
127+
a ^= i;
128+
}
129+
}
130+
int b = eor ^ a;
131+
for (int num : nums) {
132+
if (a == num) {
133+
return {a, b};
134+
}
135+
}
136+
return {b, a};
137+
}
138+
};
139+
```
140+
130141
### **Go**
131142
132143
把每个数都放到它应该在的位置,最后出现"异常"的就是重复的数和丢失的数。
@@ -148,6 +159,34 @@ func findErrorNums(nums []int) []int {
148159
}
149160
```
150161

162+
也可以使用位运算。
163+
164+
```go
165+
func findErrorNums(nums []int) []int {
166+
eor, n := 0, len(nums)
167+
for i := 1; i <= n; i++ {
168+
eor ^= (i ^ nums[i-1])
169+
}
170+
diff := eor & (-eor)
171+
a := 0
172+
for i := 1; i <= n; i++ {
173+
if (nums[i-1] & diff) == 0 {
174+
a ^= nums[i-1]
175+
}
176+
if (i & diff) == 0 {
177+
a ^= i
178+
}
179+
}
180+
b := eor ^ a
181+
for _, num := range nums {
182+
if a == num {
183+
return []int{a, b}
184+
}
185+
}
186+
return []int{b, a}
187+
}
188+
```
189+
151190
### **...**
152191

153192
```

‎solution/0600-0699/0645.Set Mismatch/README_EN.md‎

Lines changed: 53 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -36,28 +36,19 @@
3636
```python
3737
class Solution:
3838
def findErrorNums(self, nums: List[int]) -> List[int]:
39-
res = 0
40-
for num in nums:
41-
res ^= num
42-
for i in range(1, len(nums) + 1):
43-
res ^= i
44-
pos = 0
45-
while (res & 1) == 0:
46-
res >>= 1
47-
pos += 1
48-
a = b = 0
49-
for num in nums:
50-
if ((num >> pos) & 1) == 0:
51-
a ^= num
52-
else:
53-
b ^= num
54-
for i in range(1, len(nums) + 1):
55-
if ((i >> pos) & 1) == 0:
39+
eor, n = 0, len(nums)
40+
for i in range(1, n + 1):
41+
eor ^= (i ^ nums[i - 1])
42+
diff = eor & (~eor + 1)
43+
a = 0
44+
for i in range(1, n + 1):
45+
if (nums[i - 1] & diff) == 0:
46+
a ^= nums[i - 1]
47+
if (i & diff) == 0:
5648
a ^= i
57-
else:
58-
b ^= i
49+
b = eor ^ a
5950
for num in nums:
60-
if num == a:
51+
if a == num:
6152
return [a, b]
6253
return [b, a]
6354
```
@@ -67,35 +58,23 @@ class Solution:
6758
```java
6859
class Solution {
6960
public int[] findErrorNums(int[] nums) {
70-
int res = 0;
71-
for (int num : nums) {
72-
res ^= num;
73-
}
74-
for (int i = 1, n = nums.length; i < n + 1; ++i) {
75-
res ^= i;
76-
}
77-
int pos = 0;
78-
while ((res & 1) == 0) {
79-
res >>= 1;
80-
++pos;
61+
int eor = 0;
62+
for (int i = 1; i <= nums.length; ++i) {
63+
eor ^= (i ^ nums[i - 1]);
8164
}
82-
int a = 0, b = 0;
83-
for (int num : nums) {
84-
if (((num >> pos) & 1) == 0) {
85-
a ^= num;
86-
} else {
87-
b ^= num;
65+
int diff = eor & (~eor + 1);
66+
int a = 0;
67+
for (int i = 1; i <= nums.length; ++i) {
68+
if ((nums[i - 1] & diff) == 0) {
69+
a ^= nums[i - 1];
8870
}
89-
}
90-
for (int i = 1, n = nums.length; i < n + 1; ++i) {
91-
if (((i >> pos) & 1) == 0) {
71+
if ((i & diff) == 0) {
9272
a ^= i;
93-
} else {
94-
b ^= i;
9573
}
9674
}
75+
int b = eor ^ a;
9776
for (int num : nums) {
98-
if (num == a) {
77+
if (a == num) {
9978
return new int[]{a, b};
10079
}
10180
}
@@ -104,6 +83,37 @@ class Solution {
10483
}
10584
```
10685

86+
### **C++**
87+
88+
```cpp
89+
class Solution {
90+
public:
91+
vector<int> findErrorNums(vector<int>& nums) {
92+
int eor = 0, n = nums.size();
93+
for (int i = 1; i <= n; ++i) {
94+
eor ^= (i ^ nums[i - 1]);
95+
}
96+
int diff = eor & (~eor + 1);
97+
int a = 0;
98+
for (int i = 1; i <= n; ++i) {
99+
if ((nums[i - 1] & diff) == 0) {
100+
a ^= nums[i - 1];
101+
}
102+
if ((i & diff) == 0) {
103+
a ^= i;
104+
}
105+
}
106+
int b = eor ^ a;
107+
for (int num : nums) {
108+
if (a == num) {
109+
return {a, b};
110+
}
111+
}
112+
return {b, a};
113+
}
114+
};
115+
```
116+
107117
### **Go**
108118
109119
```go
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
class Solution {
2+
public:
3+
vector<int> findErrorNums(vector<int>& nums) {
4+
int eor = 0, n = nums.size();
5+
for (int i = 1; i <= n; ++i) {
6+
eor ^= (i ^ nums[i - 1]);
7+
}
8+
int diff = eor & (~eor + 1);
9+
int a = 0;
10+
for (int i = 1; i <= n; ++i) {
11+
if ((nums[i - 1] & diff) == 0) {
12+
a ^= nums[i - 1];
13+
}
14+
if ((i & diff) == 0) {
15+
a ^= i;
16+
}
17+
}
18+
int b = eor ^ a;
19+
for (int num : nums) {
20+
if (a == num) {
21+
return {a, b};
22+
}
23+
}
24+
return {b, a};
25+
}
26+
};

‎solution/0600-0699/0645.Set Mismatch/Solution.java‎

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,22 @@
11
class Solution {
22
public int[] findErrorNums(int[] nums) {
3-
int res = 0;
4-
for (int num : nums) {
5-
res ^= num;
6-
}
7-
for (int i = 1, n = nums.length; i < n + 1; ++i) {
8-
res ^= i;
9-
}
10-
int pos = 0;
11-
while ((res & 1) == 0) {
12-
res >>= 1;
13-
++pos;
3+
int eor = 0;
4+
for (int i = 1; i <= nums.length; ++i) {
5+
eor ^= (i ^ nums[i - 1]);
146
}
15-
int a = 0, b = 0;
16-
for (int num : nums) {
17-
if (((num >> pos) & 1) == 0) {
18-
a ^= num;
19-
} else {
20-
b ^= num;
7+
int diff = eor & (~eor + 1);
8+
int a = 0;
9+
for (int i = 1; i <= nums.length; ++i) {
10+
if ((nums[i - 1] & diff) == 0) {
11+
a ^= nums[i - 1];
2112
}
22-
}
23-
for (int i = 1, n = nums.length; i < n + 1; ++i) {
24-
if (((i >> pos) & 1) == 0) {
13+
if ((i & diff) == 0) {
2514
a ^= i;
26-
} else {
27-
b ^= i;
2815
}
2916
}
17+
int b = eor ^ a;
3018
for (int num : nums) {
31-
if (num == a) {
19+
if (a == num) {
3220
return new int[]{a, b};
3321
}
3422
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /