Skip to content

Commit b8c6ff9

Browse files
authored
feat: add solutions to lcci problem: No.05.04 (doocs#1388)
No.05.04.Closed Number
1 parent c590e2b commit b8c6ff9

File tree

7 files changed

+488
-2
lines changed

7 files changed

+488
-2
lines changed

lcci/05.04.Closed Number/README.md

Lines changed: 178 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
## 题目描述
66

77
<!-- 这里写题目描述 -->
8+
89
<p>下一个数。给定一个正整数,找出与其二进制表达式中1的个数相同且大小最接近的那两个数(一个略大,一个略小)。</p>
910
<p> <strong>示例1:</strong></p>
1011
<pre>
@@ -25,22 +26,198 @@
2526
## 解法
2627

2728
<!-- 这里可写通用的实现逻辑 -->
29+
30+
**方法一:位运算**
31+
32+
我们先考虑如何找出第一个比 $num$ 大且二进制表示中 $1$ 的个数相同的数。
33+
34+
我们可以从低位到高位遍历 $num$ 的相邻两个二进制位,如果低位为 $1$,且相邻的较高一位为 $0$,那么我们就找到了一个位置,我们可以将这个位置的 $0$ 变成 $1$,将这个位置的 $1$ 变成 $0$。然后我们把其余低位的 $1$ 全部移动到最低位,这样我们就得到了一个比 $num$ 大且二进制表示中 $1$ 的个数相同的数。
35+
36+
同理,我们可以找到第一个比 $num$ 小且二进制表示中 $1$ 的个数相同的数。
37+
38+
我们可以从低位到高位遍历 $num$ 的相邻两个二进制位,如果低位为 $0$,且相邻的较高一位为 $1$,那么我们就找到了一个位置,我们可以将这个位置的 $1$ 变成 $0$,将这个位置的 $0$ 变成 $1$。然后我们把其余低位的 $0$ 全部移动到最低位,这样我们就得到了一个比 $num$ 小且二进制表示中 $1$ 的个数相同的数。
39+
40+
在实现上,我们可以用一段代码来统一处理以上两种情况。
41+
42+
时间复杂度 $O(\log n)$,其中 $n$ 是 $num$ 的大小。空间复杂度 $O(1)$。
43+
2844
<!-- tabs:start -->
2945

3046
### **Python3**
3147

3248
<!-- 这里可写当前语言的特殊实现逻辑 -->
3349

3450
```python
35-
51+
class Solution:
52+
def findClosedNumbers(self, num: int) -> List[int]:
53+
ans = [-1] * 2
54+
dirs = (0, 1, 0)
55+
for p in range(2):
56+
x = num
57+
for i in range(1, 31):
58+
a, b = dirs[p], dirs[p + 1]
59+
if (x >> i & 1) == a and (x >> (i - 1) & 1) == b:
60+
x ^= 1 << i
61+
x ^= 1 << (i - 1)
62+
j, k = 0, i - 2
63+
while j < k:
64+
while j < k and (x >> j & 1) == b:
65+
j += 1
66+
while j < k and (x >> k & 1) == a:
67+
k -= 1
68+
if j < k:
69+
x ^= 1 << j
70+
x ^= 1 << k
71+
ans[p] = x
72+
break
73+
return ans
3674
```
3775

3876
### **Java**
3977

4078
<!-- 这里可写当前语言的特殊实现逻辑 -->
4179

4280
```java
81+
class Solution {
82+
public int[] findClosedNumbers(int num) {
83+
int[] ans = {-1, -1};
84+
int[] dirs = {0, 1, 0};
85+
for (int p = 0; p < 2; ++p) {
86+
int x = num;
87+
for (int i = 1; i < 31; ++i) {
88+
int a = dirs[p], b = dirs[p + 1];
89+
if ((x >> i & 1) == a && (x >> (i - 1) & 1) == b) {
90+
x ^= 1 << i;
91+
x ^= 1 << (i - 1);
92+
int j = 0, k = i - 2;
93+
while (j < k) {
94+
while (j < k && (x >> j & 1) == b) {
95+
++j;
96+
}
97+
while (j < k && (x >> k & 1) == a) {
98+
--k;
99+
}
100+
if (j < k) {
101+
x ^= 1 << j;
102+
x ^= 1 << k;
103+
}
104+
}
105+
ans[p] = x;
106+
break;
107+
}
108+
}
109+
}
110+
return ans;
111+
}
112+
}
113+
```
114+
115+
### **C++**
116+
117+
```cpp
118+
class Solution {
119+
public:
120+
vector<int> findClosedNumbers(int num) {
121+
vector<int> ans(2, -1);
122+
int dirs[3] = {0, 1, 0};
123+
for (int p = 0; p < 2; ++p) {
124+
int x = num;
125+
for (int i = 1; i < 31; ++i) {
126+
int a = dirs[p], b = dirs[p + 1];
127+
if ((x >> i & 1) == a && (x >> (i - 1) & 1) == b) {
128+
x ^= 1 << i;
129+
x ^= 1 << (i - 1);
130+
int j = 0, k = i - 2;
131+
while (j < k) {
132+
while (j < k && (x >> j & 1) == b) {
133+
++j;
134+
}
135+
while (j < k && (x >> k & 1) == a) {
136+
--k;
137+
}
138+
if (j < k) {
139+
x ^= 1 << j;
140+
x ^= 1 << k;
141+
}
142+
}
143+
ans[p] = x;
144+
break;
145+
}
146+
}
147+
}
148+
return ans;
149+
}
150+
};
151+
```
152+
153+
### **Go**
154+
155+
```go
156+
func findClosedNumbers(num int) []int {
157+
ans := []int{-1, -1}
158+
dirs := [3]int{0, 1, 0}
159+
for p := 0; p < 2; p++ {
160+
x := num
161+
for i := 1; i < 31; i++ {
162+
a, b := dirs[p], dirs[p+1]
163+
if x>>i&1 == a && x>>(i-1)&1 == b {
164+
x ^= 1 << i
165+
x ^= 1 << (i - 1)
166+
j, k := 0, i-2
167+
for j < k {
168+
for j < k && x>>j&1 == b {
169+
j++
170+
}
171+
for j < k && x>>k&1 == a {
172+
k--
173+
}
174+
if j < k {
175+
x ^= 1 << j
176+
x ^= 1 << k
177+
}
178+
}
179+
ans[p] = x
180+
break
181+
}
182+
}
183+
}
184+
return ans
185+
}
186+
```
43187

188+
### **TypeScript**
189+
190+
```ts
191+
function findClosedNumbers(num: number): number[] {
192+
const ans: number[] = [-1, -1];
193+
const dirs: number[] = [0, 1, 0];
194+
for (let p = 0; p < 2; ++p) {
195+
let x = num;
196+
for (let i = 1; i < 31; ++i) {
197+
const [a, b] = [dirs[p], dirs[p + 1]];
198+
if (((x >> i) & 1) === a && ((x >> (i - 1)) & 1) === b) {
199+
x ^= 1 << i;
200+
x ^= 1 << (i - 1);
201+
let [j, k] = [0, i - 2];
202+
while (j < k) {
203+
while (j < k && ((x >> j) & 1) === b) {
204+
++j;
205+
}
206+
while (j < k && ((x >> k) & 1) === a) {
207+
--k;
208+
}
209+
if (j < k) {
210+
x ^= 1 << j;
211+
x ^= 1 << k;
212+
}
213+
}
214+
ans[p] = x;
215+
break;
216+
}
217+
}
218+
}
219+
return ans;
220+
}
44221
```
45222

46223
### **...**

lcci/05.04.Closed Number/README_EN.md

Lines changed: 162 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,174 @@
3434
### **Python3**
3535

3636
```python
37-
37+
class Solution:
38+
def findClosedNumbers(self, num: int) -> List[int]:
39+
ans = [-1] * 2
40+
dirs = (0, 1, 0)
41+
for p in range(2):
42+
x = num
43+
for i in range(1, 31):
44+
a, b = dirs[p], dirs[p + 1]
45+
if (x >> i & 1) == a and (x >> (i - 1) & 1) == b:
46+
x ^= 1 << i
47+
x ^= 1 << (i - 1)
48+
j, k = 0, i - 2
49+
while j < k:
50+
while j < k and (x >> j & 1) == b:
51+
j += 1
52+
while j < k and (x >> k & 1) == a:
53+
k -= 1
54+
if j < k:
55+
x ^= 1 << j
56+
x ^= 1 << k
57+
ans[p] = x
58+
break
59+
return ans
3860
```
3961

4062
### **Java**
4163

4264
```java
65+
class Solution {
66+
public int[] findClosedNumbers(int num) {
67+
int[] ans = {-1, -1};
68+
int[] dirs = {0, 1, 0};
69+
for (int p = 0; p < 2; ++p) {
70+
int x = num;
71+
for (int i = 1; i < 31; ++i) {
72+
int a = dirs[p], b = dirs[p + 1];
73+
if ((x >> i & 1) == a && (x >> (i - 1) & 1) == b) {
74+
x ^= 1 << i;
75+
x ^= 1 << (i - 1);
76+
int j = 0, k = i - 2;
77+
while (j < k) {
78+
while (j < k && (x >> j & 1) == b) {
79+
++j;
80+
}
81+
while (j < k && (x >> k & 1) == a) {
82+
--k;
83+
}
84+
if (j < k) {
85+
x ^= 1 << j;
86+
x ^= 1 << k;
87+
}
88+
}
89+
ans[p] = x;
90+
break;
91+
}
92+
}
93+
}
94+
return ans;
95+
}
96+
}
97+
```
98+
99+
### **C++**
100+
101+
```cpp
102+
class Solution {
103+
public:
104+
vector<int> findClosedNumbers(int num) {
105+
vector<int> ans(2, -1);
106+
int dirs[3] = {0, 1, 0};
107+
for (int p = 0; p < 2; ++p) {
108+
int x = num;
109+
for (int i = 1; i < 31; ++i) {
110+
int a = dirs[p], b = dirs[p + 1];
111+
if ((x >> i & 1) == a && (x >> (i - 1) & 1) == b) {
112+
x ^= 1 << i;
113+
x ^= 1 << (i - 1);
114+
int j = 0, k = i - 2;
115+
while (j < k) {
116+
while (j < k && (x >> j & 1) == b) {
117+
++j;
118+
}
119+
while (j < k && (x >> k & 1) == a) {
120+
--k;
121+
}
122+
if (j < k) {
123+
x ^= 1 << j;
124+
x ^= 1 << k;
125+
}
126+
}
127+
ans[p] = x;
128+
break;
129+
}
130+
}
131+
}
132+
return ans;
133+
}
134+
};
135+
```
136+
137+
### **Go**
138+
139+
```go
140+
func findClosedNumbers(num int) []int {
141+
ans := []int{-1, -1}
142+
dirs := [3]int{0, 1, 0}
143+
for p := 0; p < 2; p++ {
144+
x := num
145+
for i := 1; i < 31; i++ {
146+
a, b := dirs[p], dirs[p+1]
147+
if x>>i&1 == a && x>>(i-1)&1 == b {
148+
x ^= 1 << i
149+
x ^= 1 << (i - 1)
150+
j, k := 0, i-2
151+
for j < k {
152+
for j < k && x>>j&1 == b {
153+
j++
154+
}
155+
for j < k && x>>k&1 == a {
156+
k--
157+
}
158+
if j < k {
159+
x ^= 1 << j
160+
x ^= 1 << k
161+
}
162+
}
163+
ans[p] = x
164+
break
165+
}
166+
}
167+
}
168+
return ans
169+
}
170+
```
43171

172+
### **TypeScript**
173+
174+
```ts
175+
function findClosedNumbers(num: number): number[] {
176+
const ans: number[] = [-1, -1];
177+
const dirs: number[] = [0, 1, 0];
178+
for (let p = 0; p < 2; ++p) {
179+
let x = num;
180+
for (let i = 1; i < 31; ++i) {
181+
const [a, b] = [dirs[p], dirs[p + 1]];
182+
if (((x >> i) & 1) === a && ((x >> (i - 1)) & 1) === b) {
183+
x ^= 1 << i;
184+
x ^= 1 << (i - 1);
185+
let [j, k] = [0, i - 2];
186+
while (j < k) {
187+
while (j < k && ((x >> j) & 1) === b) {
188+
++j;
189+
}
190+
while (j < k && ((x >> k) & 1) === a) {
191+
--k;
192+
}
193+
if (j < k) {
194+
x ^= 1 << j;
195+
x ^= 1 << k;
196+
}
197+
}
198+
ans[p] = x;
199+
break;
200+
}
201+
}
202+
}
203+
return ans;
204+
}
44205
```
45206

46207
### **...**

0 commit comments

Comments
 (0)