29
29
30
30
## 解法
31
31
32
- 异或运算求解。
32
+ ** 方法一:位运算 **
33
33
34
- 首先明确,两个相同的数异或之后的结果为 0。对该数组所有元素进行异或运算,结果就是 ** 两个只出现一次的数字异或的结果 ** ,即 ` eor = a ^ b `
34
+ 由于数组中除了两个数字之外,其他数字都出现了两次,因此对数组中的所有数字进行异或运算,得到的结果即为两个只出现一次的数字的异或结果。
35
35
36
- 找出这个结果 eor 中最后一个二进制位为 1 而其余位为 0 的数,即 ` eor & (~eor + 1) ` ,之后遍历数组所有元素,二进制位为 0 的元素异或到 a 。
36
+ 由于这两个数字不相等,因此异或结果中至少存在一位为 $1$。我们通过 ` lowbit ` 运算找到异或结果中最低位的 $1$,并将数组中的所有数字按照该位是否为 $1$ 分为两组,这样两个只出现一次的数字就被分到了不同的组中 。
37
37
38
- 遍历结束后 ` b = eor ^ a ` ,返回结果即可。
38
+ 对两个组分别进行异或运算,即可得到两个只出现一次的数字。
39
+
40
+ 时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为数组长度。
39
41
40
42
<!-- tabs:start -->
41
43
44
46
``` python
45
47
class Solution :
46
48
def singleNumbers (self , nums : List[int ]) -> List[int ]:
47
- eor = 0
48
- for num in nums:
49
- eor ^= num
50
- # 找出最右边的 1
51
- diff = eor & (~ eor + 1 )
49
+ xs = reduce (xor, nums)
52
50
a = 0
53
- for num in nums:
54
- if (num & diff) == 0 :
55
- a ^= num
56
- b = eor ^ a
51
+ lb = xs & - xs
52
+ for x in nums:
53
+ if x & lb:
54
+ a ^= x
55
+ b = xs ^ a
57
56
return [a, b]
58
57
```
59
58
@@ -62,24 +61,66 @@ class Solution:
62
61
``` java
63
62
class Solution {
64
63
public int [] singleNumbers (int [] nums ) {
65
- int eor = 0 ;
66
- for (int num : nums) {
67
- eor ^ = num ;
64
+ int xs = 0 ;
65
+ for (int x : nums) {
66
+ xs ^ = x ;
68
67
}
69
- // # 找出最右边的 1
70
- int diff = eor & (~ eor + 1 );
68
+ int lb = xs & - xs;
71
69
int a = 0 ;
72
- for (int num : nums) {
73
- if ((num & diff) = = 0 ) {
74
- a ^ = num ;
70
+ for (int x : nums) {
71
+ if ((x & lb) ! = 0 ) {
72
+ a ^ = x ;
75
73
}
76
74
}
77
- int b = eor ^ a;
75
+ int b = xs ^ a;
78
76
return new int [] {a, b};
79
77
}
80
78
}
81
79
```
82
80
81
+ ### ** C++**
82
+
83
+ ``` cpp
84
+ class Solution {
85
+ public:
86
+ vector<int > singleNumbers(vector<int >& nums) {
87
+ int xs = 0;
88
+ for (int& x : nums) {
89
+ xs ^= x;
90
+ }
91
+ int lb = xs & -xs;
92
+ int a = 0;
93
+ for (int& x : nums) {
94
+ if (x & lb) {
95
+ a ^= x;
96
+ }
97
+ }
98
+ int b = xs ^ a;
99
+ return {a, b};
100
+ }
101
+ };
102
+ ```
103
+
104
+ ### **Go**
105
+
106
+ ```go
107
+ func singleNumbers(nums []int) []int {
108
+ xs := 0
109
+ for _, x := range nums {
110
+ xs ^= x
111
+ }
112
+ lb := xs & -xs
113
+ a := 0
114
+ for _, x := range nums {
115
+ if x&lb != 0 {
116
+ a ^= x
117
+ }
118
+ }
119
+ b := xs ^ a
120
+ return []int{a, b}
121
+ }
122
+ ```
123
+
83
124
### ** JavaScript**
84
125
85
126
``` js
@@ -88,18 +129,18 @@ class Solution {
88
129
* @return {number[]}
89
130
*/
90
131
var singleNumbers = function (nums ) {
91
- let eor = 0 ;
92
- for (let num of nums) {
93
- eor ^= num ;
132
+ let xs = 0 ;
133
+ for (const x of nums) {
134
+ xs ^= x ;
94
135
}
95
- const diff = eor & ( ~ eor + 1 ) ;
136
+ const lb = xs & - xs ;
96
137
let a = 0 ;
97
- for (let num of nums) {
98
- if ((num & diff) == 0 ) {
99
- a ^= num ;
138
+ for (const x of nums) {
139
+ if (x & lb ) {
140
+ a ^= x ;
100
141
}
101
142
}
102
- let b = eor ^ a;
143
+ const b = xs ^ a;
103
144
return [a, b];
104
145
};
105
146
```
@@ -109,21 +150,40 @@ var singleNumbers = function (nums) {
109
150
``` cs
110
151
public class Solution {
111
152
public int [] SingleNumbers (int [] nums ) {
112
- int eor = 0 ;
113
- foreach (var num in nums ) {
114
- eor ^= num ;
153
+ int xs = 0 ;
154
+ foreach (int x in nums ) {
155
+ xs ^= x ;
115
156
}
116
- int diff = eor & ( ~ eor + 1 ) ;
157
+ int lb = xs & - xs ;
117
158
int a = 0 ;
118
- foreach (var num in nums ) {
119
- if ((num & diff ) = = 0 ) {
120
- a ^= num ;
159
+ foreach (int x in nums ) {
160
+ if ((x & lb ) ! = 0 ) {
161
+ a ^= x ;
121
162
}
122
163
}
123
- int b = eor ^ a ;
164
+ int b = xs ^ a ;
165
+ return new int [] {a , b };
166
+ }
167
+ }
168
+ ```
124
169
125
- return new int []{a , b };
170
+ ### ** TypeScript**
171
+
172
+ ``` ts
173
+ function singleNumbers(nums : number []): number [] {
174
+ let xs = 0 ;
175
+ for (const x of nums ) {
176
+ xs ^= x ;
126
177
}
178
+ const lb = xs & - xs ;
179
+ let a = 0 ;
180
+ for (const x of nums ) {
181
+ if (x & lb ) {
182
+ a ^= x ;
183
+ }
184
+ }
185
+ const b = xs ^ a ;
186
+ return [a , b ];
127
187
}
128
188
```
129
189
0 commit comments