Skip to content

Commit 595d6c4

Browse files
committed
feat: add solutions to lcof problems: No.56.1,56.2
1 parent da3b626 commit 595d6c4

File tree

15 files changed

+339
-136
lines changed

15 files changed

+339
-136
lines changed

lcof/面试题56 - I. 数组中数字出现的次数/README.md

+99-39
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,15 @@
2929

3030
## 解法
3131

32-
异或运算求解。
32+
**方法一:位运算**
3333

34-
首先明确,两个相同的数异或之后的结果为 0。对该数组所有元素进行异或运算,结果就是**两个只出现一次的数字异或的结果**,即 `eor = a ^ b`
34+
由于数组中除了两个数字之外,其他数字都出现了两次,因此对数组中的所有数字进行异或运算,得到的结果即为两个只出现一次的数字的异或结果。
3535

36-
找出这个结果 eor 中最后一个二进制位为 1 而其余位为 0 的数,即 `eor & (~eor + 1)`,之后遍历数组所有元素,二进制位为 0 的元素异或到 a
36+
由于这两个数字不相等,因此异或结果中至少存在一位为 $1$。我们通过 `lowbit` 运算找到异或结果中最低位的 $1$,并将数组中的所有数字按照该位是否为 $1$ 分为两组,这样两个只出现一次的数字就被分到了不同的组中
3737

38-
遍历结束后 `b = eor ^ a`,返回结果即可。
38+
对两个组分别进行异或运算,即可得到两个只出现一次的数字。
39+
40+
时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为数组长度。
3941

4042
<!-- tabs:start -->
4143

@@ -44,16 +46,13 @@
4446
```python
4547
class Solution:
4648
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)
5250
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
5756
return [a, b]
5857
```
5958

@@ -62,24 +61,66 @@ class Solution:
6261
```java
6362
class Solution {
6463
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;
6867
}
69-
// # 找出最右边的 1
70-
int diff = eor & (~eor + 1);
68+
int lb = xs & - xs;
7169
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;
7573
}
7674
}
77-
int b = eor ^ a;
75+
int b = xs ^ a;
7876
return new int[] {a, b};
7977
}
8078
}
8179
```
8280

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+
83124
### **JavaScript**
84125

85126
```js
@@ -88,18 +129,18 @@ class Solution {
88129
* @return {number[]}
89130
*/
90131
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;
94135
}
95-
const diff = eor & (~eor + 1);
136+
const lb = xs & -xs;
96137
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;
100141
}
101142
}
102-
let b = eor ^ a;
143+
const b = xs ^ a;
103144
return [a, b];
104145
};
105146
```
@@ -109,21 +150,40 @@ var singleNumbers = function (nums) {
109150
```cs
110151
public class Solution {
111152
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;
115156
}
116-
int diff = eor & (~eor + 1);
157+
int lb = xs & - xs;
117158
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;
121162
}
122163
}
123-
int b = eor ^ a;
164+
int b = xs ^ a;
165+
return new int[] {a, b};
166+
}
167+
}
168+
```
124169

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;
126177
}
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];
127187
}
128188
```
129189

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
class Solution {
2+
public:
3+
vector<int> singleNumbers(vector<int>& nums) {
4+
int xs = 0;
5+
for (int& x : nums) {
6+
xs ^= x;
7+
}
8+
int lb = xs & -xs;
9+
int a = 0;
10+
for (int& x : nums) {
11+
if (x & lb) {
12+
a ^= x;
13+
}
14+
}
15+
int b = xs ^ a;
16+
return {a, b};
17+
}
18+
};
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
public class Solution {
22
public int[] SingleNumbers(int[] nums) {
3-
int eor = 0;
4-
foreach(var num in nums) {
5-
eor ^= num;
3+
int xs = 0;
4+
foreach(int x in nums) {
5+
xs ^= x;
66
}
7-
int diff = eor & (~eor + 1);
7+
int lb = xs & - xs;
88
int a = 0;
9-
foreach(var num in nums) {
10-
if ((num & diff) == 0) {
11-
a ^= num;
9+
foreach(int x in nums) {
10+
if ((x & lb) != 0) {
11+
a ^= x;
1212
}
1313
}
14-
int b = eor ^ a;
15-
16-
return new int[]{a, b};
14+
int b = xs ^ a;
15+
return new int[] {a, b};
1716
}
1817
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
func singleNumbers(nums []int) []int {
2+
xs := 0
3+
for _, x := range nums {
4+
xs ^= x
5+
}
6+
lb := xs & -xs
7+
a := 0
8+
for _, x := range nums {
9+
if x&lb != 0 {
10+
a ^= x
11+
}
12+
}
13+
b := xs ^ a
14+
return []int{a, b}
15+
}
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
class Solution {
22
public int[] singleNumbers(int[] nums) {
3-
int eor = 0;
4-
for (int num : nums) {
5-
eor ^= num;
3+
int xs = 0;
4+
for (int x : nums) {
5+
xs ^= x;
66
}
7-
// # 找出最右边的 1
8-
int diff = eor & (~eor + 1);
7+
int lb = xs & - xs;
98
int a = 0;
10-
for (int num : nums) {
11-
if ((num & diff) == 0) {
12-
a ^= num;
9+
for (int x : nums) {
10+
if ((x & lb) != 0) {
11+
a ^= x;
1312
}
1413
}
15-
int b = eor ^ a;
14+
int b = xs ^ a;
1615
return new int[] {a, b};
1716
}
1817
}

lcof/面试题56 - I. 数组中数字出现的次数/Solution.js

+8-8
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@
33
* @return {number[]}
44
*/
55
var singleNumbers = function (nums) {
6-
let eor = 0;
7-
for (let num of nums) {
8-
eor ^= num;
6+
let xs = 0;
7+
for (const x of nums) {
8+
xs ^= x;
99
}
10-
const diff = eor & (~eor + 1);
10+
const lb = xs & -xs;
1111
let a = 0;
12-
for (let num of nums) {
13-
if ((num & diff) == 0) {
14-
a ^= num;
12+
for (const x of nums) {
13+
if (x & lb) {
14+
a ^= x;
1515
}
1616
}
17-
let b = eor ^ a;
17+
const b = xs ^ a;
1818
return [a, b];
1919
};
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
class Solution:
22
def singleNumbers(self, nums: List[int]) -> List[int]:
3-
eor = 0
4-
for num in nums:
5-
eor ^= num
6-
# 找出最右边的 1
7-
diff = eor & (~eor + 1)
3+
xs = reduce(xor, nums)
84
a = 0
9-
for num in nums:
10-
if (num & diff) == 0:
11-
a ^= num
12-
b = eor ^ a
5+
lb = xs & -xs
6+
for x in nums:
7+
if x & lb:
8+
a ^= x
9+
b = xs ^ a
1310
return [a, b]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
function singleNumbers(nums: number[]): number[] {
2+
let xs = 0;
3+
for (const x of nums) {
4+
xs ^= x;
5+
}
6+
const lb = xs & -xs;
7+
let a = 0;
8+
for (const x of nums) {
9+
if (x & lb) {
10+
a ^= x;
11+
}
12+
}
13+
const b = xs ^ a;
14+
return [a, b];
15+
}

0 commit comments

Comments
 (0)