Skip to content

Commit c8dd797

Browse files
committed
feat: add solutions to lc problem: No.2429
No.2429.Minimize XOR
1 parent 46fb78f commit c8dd797

File tree

7 files changed

+316
-226
lines changed

7 files changed

+316
-226
lines changed

solution/2400-2499/2429.Minimize XOR/README.md

Lines changed: 136 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,9 @@ num1 和 num2 的二进制表示分别是 0001 和 1100 。
5353

5454
**方法一:贪心 + 位运算**
5555

56-
根据题意,我们要找到一个整数 `x`,使得 `x` 的置位数和 `num2` 相同,且 `x XOR num1` 的值最小
56+
根据题目描述,我们先求出 $num2$ 的置位数 $cnt$,然后从高位到低位枚举 $num1$ 的每一位,如果该位为 $1$,则将 $x$ 的对应位设为 $1$,并将 $cnt$ 减 $1$,直到 $cnt$ 为 $0$。如果此时 $cnt$ 仍不为 $0$,则从低位开始将 $num1$ 的每一位为 $0$ 的位置设为 $1$,并将 $cnt$ 减 $1$,直到 $cnt$ 为 $0$
5757

58-
先求出 `num2` 的置位数,我们记为 `cnt`
59-
60-
接着从 `num1` 二进制的最高位开始,依次向低位遍历,如果当前位为 `1`,则 `x` 的当前位也应该为 `1`,并且将 `cnt` 减一。如果 `cnt``0`,则说明 `x` 的置位数已经和 `num2` 相同,此时 `x XOR num1` 的值就是最小的,直接返回即可。
61-
62-
如果遍历完 `num1` 的二进制表示后,`cnt` 不为 `0`,说明 `x` 的置位数还没有和 `num2` 相同,此时我们需要将 `x` 的低位补 `1`,直到 `x` 的置位数和 `num2` 相同为止。
63-
64-
时间复杂度 $O(\log n)$。其中 $n$ 为 `num1` 的值。
58+
时间复杂度 $O(\log n)$,空间复杂度 $O(1)$。其中 $n$ 为 $num1$ 和 $num2$ 的最大值。
6559

6660
<!-- tabs:start -->
6761

@@ -73,20 +67,30 @@ num1 和 num2 的二进制表示分别是 0001 和 1100 。
7367
class Solution:
7468
def minimizeXor(self, num1: int, num2: int) -> int:
7569
cnt = num2.bit_count()
76-
ans = 0
70+
x = 0
7771
for i in range(30, -1, -1):
78-
if (num1 >> i) & 1:
79-
ans |= 1 << i
72+
if num1 >> i & 1 and cnt:
73+
x |= 1 << i
8074
cnt -= 1
81-
if cnt == 0:
82-
return ans
83-
for i in range(31):
84-
if (num1 >> i) & 1 == 0:
85-
ans |= 1 << i
75+
for i in range(30):
76+
if num1 >> i & 1 ^ 1 and cnt:
77+
x |= 1 << i
8678
cnt -= 1
87-
if cnt == 0:
88-
return ans
89-
return 0
79+
return x
80+
```
81+
82+
```python
83+
class Solution:
84+
def minimizeXor(self, num1: int, num2: int) -> int:
85+
cnt1 = num1.bit_count()
86+
cnt2 = num2.bit_count()
87+
while cnt1 > cnt2:
88+
num1 &= (num1 - 1)
89+
cnt1 -= 1
90+
while cnt1 < cnt2:
91+
num1 |= (num1 + 1)
92+
cnt1 += 1
93+
return num1
9094
```
9195

9296
### **Java**
@@ -97,24 +101,36 @@ class Solution:
97101
class Solution {
98102
public int minimizeXor(int num1, int num2) {
99103
int cnt = Integer.bitCount(num2);
100-
int ans = 0;
101-
for (int i = 30; i >= 0; --i) {
102-
if (((num1 >> i) & 1) == 1) {
103-
ans |= 1 << i;
104-
if (--cnt == 0) {
105-
return ans;
106-
}
104+
int x = 0;
105+
for (int i = 30; i >= 0 && cnt > 0; --i) {
106+
if ((num1 >> i & 1) == 1) {
107+
x |= 1 << i;
108+
--cnt;
107109
}
108110
}
109-
for (int i = 0; i < 31; ++i) {
110-
if (((num1 >> i) & 1) == 0) {
111-
ans |= 1 << i;
112-
if (--cnt == 0) {
113-
return ans;
114-
}
111+
for (int i = 0; cnt > 0; ++i) {
112+
if ((num1 >> i & 1) == 0) {
113+
x |= 1 << i;
114+
--cnt;
115115
}
116116
}
117-
return 0;
117+
return x;
118+
}
119+
}
120+
```
121+
122+
```java
123+
class Solution {
124+
public int minimizeXor(int num1, int num2) {
125+
int cnt1 = Integer.bitCount(num1);
126+
int cnt2 = Integer.bitCount(num2);
127+
for (; cnt1 > cnt2; --cnt1) {
128+
num1 &= (num1 - 1);
129+
}
130+
for (; cnt1 < cnt2; ++cnt1) {
131+
num1 |= (num1 + 1);
132+
}
133+
return num1;
118134
}
119135
}
120136
```
@@ -126,24 +142,37 @@ class Solution {
126142
public:
127143
int minimizeXor(int num1, int num2) {
128144
int cnt = __builtin_popcount(num2);
129-
int ans = 0;
130-
for (int i = 30; i >= 0; --i) {
131-
if ((num1 >> i) & 1) {
132-
ans |= 1 << i;
133-
if (--cnt == 0) {
134-
return ans;
135-
}
145+
int x = 0;
146+
for (int i = 30; ~i && cnt; --i) {
147+
if (num1 >> i & 1) {
148+
x |= 1 << i;
149+
--cnt;
136150
}
137151
}
138-
for (int i = 0; i < 31; ++i) {
139-
if (((num1 >> i) & 1) == 0) {
140-
ans |= 1 << i;
141-
if (--cnt == 0) {
142-
return ans;
143-
}
152+
for (int i = 0; cnt; ++i) {
153+
if (num1 >> i & 1 ^ 1) {
154+
x |= 1 << i;
155+
--cnt;
144156
}
145157
}
146-
return 0;
158+
return x;
159+
}
160+
};
161+
```
162+
163+
```cpp
164+
class Solution {
165+
public:
166+
int minimizeXor(int num1, int num2) {
167+
int cnt1 = __builtin_popcount(num1);
168+
int cnt2 = __builtin_popcount(num2);
169+
for (; cnt1 > cnt2; --cnt1) {
170+
num1 &= (num1 - 1);
171+
}
172+
for (; cnt1 < cnt2; ++cnt1) {
173+
num1 |= (num1 + 1);
174+
}
175+
return num1;
147176
}
148177
};
149178
```
@@ -153,51 +182,83 @@ public:
153182
```go
154183
func minimizeXor(num1 int, num2 int) int {
155184
cnt := bits.OnesCount(uint(num2))
156-
ans := 0
157-
for i := 30; i >= 0; i-- {
185+
x := 0
186+
for i := 30; i >= 0 && cnt > 0; i-- {
158187
if num1>>i&1 == 1 {
159-
ans |= 1 << i
188+
x |= 1 << i
160189
cnt--
161-
if cnt == 0 {
162-
return ans
163-
}
164190
}
165191
}
166-
for i := 0; i < 31; i++ {
192+
for i := 0; cnt > 0; i++ {
167193
if num1>>i&1 == 0 {
168-
ans |= 1 << i
194+
x |= 1 << i
169195
cnt--
170-
if cnt == 0 {
171-
return ans
172-
}
173196
}
174197
}
175-
return 0
198+
return x
199+
}
200+
```
201+
202+
```go
203+
func minimizeXor(num1 int, num2 int) int {
204+
cnt1 := bits.OnesCount(uint(num1))
205+
cnt2 := bits.OnesCount(uint(num2))
206+
for ; cnt1 > cnt2; cnt1-- {
207+
num1 &= (num1 - 1)
208+
}
209+
for ; cnt1 < cnt2; cnt1++ {
210+
num1 |= (num1 + 1)
211+
}
212+
return num1
176213
}
177214
```
178215

179216
### **TypeScript**
180217

181218
```ts
182219
function minimizeXor(num1: number, num2: number): number {
183-
let ans = num1;
184-
let target = num1
185-
.toString(2)
186-
.split('')
187-
.reduce((a, c) => a + Number(c), 0);
188-
let count = num2
189-
.toString(2)
190-
.split('')
191-
.reduce((a, c) => a + Number(c), 0);
192-
while (count > target) {
193-
ans |= ans + 1;
194-
count -= 1;
220+
let cnt = 0;
221+
while (num2) {
222+
num2 &= num2 - 1;
223+
++cnt;
195224
}
196-
while (count < target) {
197-
ans &= ans - 1;
198-
count += 1;
225+
let x = 0;
226+
for (let i = 30; i >= 0 && cnt > 0; --i) {
227+
if ((num1 >> i) & 1) {
228+
x |= 1 << i;
229+
--cnt;
230+
}
199231
}
200-
return ans;
232+
for (let i = 0; cnt > 0; ++i) {
233+
if (!((num1 >> i) & 1)) {
234+
x |= 1 << i;
235+
--cnt;
236+
}
237+
}
238+
return x;
239+
}
240+
```
241+
242+
```ts
243+
function minimizeXor(num1: number, num2: number): number {
244+
let cnt1 = bitCount(num1);
245+
let cnt2 = bitCount(num2);
246+
for (; cnt1 > cnt2; --cnt1) {
247+
num1 &= num1 - 1;
248+
}
249+
for (; cnt1 < cnt2; ++cnt1) {
250+
num1 |= num1 + 1;
251+
}
252+
return num1;
253+
}
254+
255+
function bitCount(i: number): number {
256+
i = i - ((i >>> 1) & 0x55555555);
257+
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
258+
i = (i + (i >>> 4)) & 0x0f0f0f0f;
259+
i = i + (i >>> 8);
260+
i = i + (i >>> 16);
261+
return i & 0x3f;
201262
}
202263
```
203264

0 commit comments

Comments
 (0)