@@ -79,317 +79,32 @@ tags:
79
79
80
80
<!-- solution:start -->
81
81
82
- ### 方法一:双指针 + 位运算
83
-
84
- 根据题目描述,我们需要求出数组 $nums$ 下标 $l$ 到 $r$ 的元素的按位与运算的结果,即 $nums[ l] \& nums[ l + 1] \& \cdots \& nums[ r] $。
85
-
86
- 如果我们每次固定右端点 $r$,那么左端点 $l$ 的范围是 $[ 0, r] $。每次移动右端点 $r$,按位与的结果只会变小,我们用一个变量 $s$ 记录当前的按位与的结果,如果 $s$ 小于 $k$,我们就将左端点 $l$ 向右移动,直到 $s$ 大于等于 $k$。在移动左端点 $l$ 的过程中,我们需要维护一个数组 $cnt$,记录当前区间内每个二进制位上 $0$ 的个数,当 $cnt[ h] $ 为 $0$ 时,说明当前区间内的元素在第 $h$ 位上都为 $1$,我们就可以将 $s$ 的第 $h$ 位设置为 $1$。
87
-
88
- 时间复杂度 $O(n \times \log M)$,空间复杂度 $O(\log M)$。其中 $n$ 和 $M$ 分别是数组 $nums$ 的长度和数组 $nums$ 中的最大值。
89
-
90
- 相似题目:
91
-
92
- - [ 3097. 或值至少为 K 的最短子数组 II] ( https://github.com/doocs/leetcode/blob/main/solution/3000-3099/3097.Shortest%20Subarray%20With%20OR%20at%20Least%20K%20II/README.md )
82
+ ### 方法一
93
83
94
84
<!-- tabs:start -->
95
85
96
86
#### Python3
97
87
98
88
``` python
99
- class Solution :
100
- def minimumDifference (self , nums : List[int ], k : int ) -> int :
101
- m = max (nums).bit_length()
102
- cnt = [0 ] * m
103
- s, i = - 1 , 0
104
- ans = inf
105
- for j, x in enumerate (nums):
106
- s &= x
107
- ans = min (ans, abs (s - k))
108
- for h in range (m):
109
- if x >> h & 1 ^ 1 :
110
- cnt[h] += 1
111
- while i < j and s < k:
112
- y = nums[i]
113
- for h in range (m):
114
- if y >> h & 1 ^ 1 :
115
- cnt[h] -= 1
116
- if cnt[h] == 0 :
117
- s |= 1 << h
118
- i += 1
119
- ans = min (ans, abs (s - k))
120
- return ans
121
- ```
122
-
123
- #### Java
124
-
125
- ``` java
126
- class Solution {
127
- public int minimumDifference (int [] nums , int k ) {
128
- int mx = 0 ;
129
- for (int x : nums) {
130
- mx = Math . max(mx, x);
131
- }
132
- int m = 32 - Integer . numberOfLeadingZeros(mx);
133
- int [] cnt = new int [m];
134
- int n = nums. length;
135
- int ans = Integer . MAX_VALUE ;
136
- for (int i = 0 , j = 0 , s = - 1 ; j < n; ++ j) {
137
- s &= nums[j];
138
- ans = Math . min(ans, Math . abs(s - k));
139
- for (int h = 0 ; h < m; ++ h) {
140
- if ((nums[j] >> h & 1 ) == 0 ) {
141
- ++ cnt[h];
142
- }
143
- }
144
- while (i < j && s < k) {
145
- for (int h = 0 ; h < m; ++ h) {
146
- if ((nums[i] >> h & 1 ) == 0 && -- cnt[h] == 0 ) {
147
- s |= 1 << h;
148
- }
149
- }
150
- ++ i;
151
- ans = Math . min(ans, Math . abs(s - k));
152
- }
153
- }
154
- return ans;
155
- }
156
- }
157
- ```
158
89
159
- #### C++
160
-
161
- ``` cpp
162
- class Solution {
163
- public:
164
- int minimumDifference(vector<int >& nums, int k) {
165
- int mx = * max_element(nums.begin(), nums.end());
166
- int m = 32 - __ builtin_clz(mx);
167
- int n = nums.size();
168
- int ans = INT_MAX;
169
- vector<int > cnt(m);
170
- for (int i = 0, j = 0, s = -1; j < n; ++j) {
171
- s &= nums[ j] ;
172
- ans = min(ans, abs(s - k));
173
- for (int h = 0; h < m; ++h) {
174
- if (nums[ j] >> h & 1 ^ 1) {
175
- ++cnt[ h] ;
176
- }
177
- }
178
- while (i < j && s < k) {
179
- for (int h = 0; h < m; ++h) {
180
- if (nums[ i] >> h & 1 ^ 1 && --cnt[ h] == 0) {
181
- s |= 1 << h;
182
- }
183
- }
184
- ans = min(ans, abs(s - k));
185
- ++i;
186
- }
187
- }
188
- return ans;
189
- }
190
- };
191
- ```
192
-
193
- #### Go
194
-
195
- ```go
196
- func minimumDifference(nums []int, k int) int {
197
- m := bits.Len(uint(slices.Max(nums)))
198
- cnt := make([]int, m)
199
- ans := math.MaxInt32
200
- s, i := -1, 0
201
- for j, x := range nums {
202
- s &= x
203
- ans = min(ans, abs(s-k))
204
- for h := 0; h < m; h++ {
205
- if x>>h&1 == 0 {
206
- cnt[h]++
207
- }
208
- }
209
- for i < j && s < k {
210
- y := nums[i]
211
- for h := 0; h < m; h++ {
212
- if y>>h&1 == 0 {
213
- cnt[h]--
214
- if cnt[h] == 0 {
215
- s |= 1 << h
216
- }
217
- }
218
- }
219
- ans = min(ans, abs(s-k))
220
- i++
221
- }
222
- }
223
- return ans
224
- }
225
-
226
- func abs(x int) int {
227
- if x < 0 {
228
- return -x
229
- }
230
- return x
231
- }
232
- ```
233
-
234
- #### TypeScript
235
-
236
- ``` ts
237
- function minimumDifference(nums : number [], k : number ): number {
238
- const m = Math .max (... nums ).toString (2 ).length ;
239
- const n = nums .length ;
240
- const cnt: number [] = numsay (m ).fill (0 );
241
- let ans = Infinity ;
242
- for (let i = 0 , j = 0 , s = - 1 ; j < n ; ++ j ) {
243
- s &= nums [j ];
244
- ans = Math .min (ans , Math .abs (s - k ));
245
- for (let h = 0 ; h < m ; ++ h ) {
246
- if (((nums [j ] >> h ) & 1 ) ^ 1 ) {
247
- ++ cnt [h ];
248
- }
249
- }
250
- while (i < j && s < k ) {
251
- for (let h = 0 ; h < m ; ++ h ) {
252
- if (((nums [i ] >> h ) & 1 ) ^ 1 && -- cnt [h ] === 0 ) {
253
- s |= 1 << h ;
254
- }
255
- }
256
- ans = Math .min (ans , Math .abs (s - k ));
257
- ++ i ;
258
- }
259
- }
260
- return ans ;
261
- }
262
- ```
263
-
264
- <!-- tabs: end -->
265
-
266
- <!-- solution: end -->
267
-
268
- <!-- solution: start -->
269
-
270
- ### 方法二:哈希表 + 枚举
271
-
272
- 根据题目描述,我们需要求出数组 $nums$ 下标 $l$ 到 $r$ 的元素的按位与运算的结果,即 $nums[ l] \& nums[ l + 1] \& \cdots \& nums[ r] $。
273
-
274
- 如果我们每次固定右端点 $r$,那么左端点 $l$ 的范围是 $[ 0, r] $。由于按位与之和随着 $l$ 的减小而单调递减,并且 $nums[ i] $ 的值不超过 $10^9$,因此区间 $[ 0, r] $ 最多只有 $30$ 种不同的值。因此,我们可以用一个集合来维护所有的 $nums[ l] \& nums[ l + 1] \& \cdots \& nums[ r] $ 的值。当我们从 $r$ 遍历到 $r+1$ 时,以 $r+1$ 为右端点的值,就是集合中每个值与 $nums[ r + 1] $ 进行按位与运算得到的值,再加上 $nums[ r + 1] $ 本身。因此,我们只需要枚举集合中的每个值,与 $nums[ r] $ 进行按位与运算,就可以得到以 $r$ 为右端点的所有值,将每个值与 $k$ 相减后取绝对值,就可以得到以 $r$ 为右端点的所有值与 $k$ 的差的绝对值,其中的最小值就是答案。
275
-
276
- 时间复杂度 $O(n \times \log M)$,空间复杂度 $O(\log M)$。其中 $n$ 和 $M$ 分别是数组 $nums$ 的长度和数组 $nums$ 中的最大值。
277
-
278
- 相似题目:
279
-
280
- - [ 1521. 找到最接近目标值的函数值] ( https://github.com/doocs/leetcode/blob/main/solution/1500-1599/1521.Find%20a%20Value%20of%20a%20Mysterious%20Function%20Closest%20to%20Target/README.md )
281
-
282
- <!-- tabs: start -->
283
-
284
- #### Python3
285
-
286
- ``` python
287
- class Solution :
288
- def minimumDifference (self , nums : List[int ], k : int ) -> int :
289
- ans = abs (nums[0 ] - k)
290
- s = {nums[0 ]}
291
- for x in nums:
292
- s = {x & y for y in s} | {x}
293
- ans = min (ans, min (abs (y - k) for y in s))
294
- return ans
295
90
```
296
91
297
92
#### Java
298
93
299
94
``` java
300
- class Solution {
301
- public int minimumDifference (int [] nums , int k ) {
302
- int ans = Math . abs(nums[0 ] - k);
303
- Set<Integer > pre = new HashSet<> ();
304
- pre. add(nums[0 ]);
305
- for (int x : nums) {
306
- Set<Integer > cur = new HashSet<> ();
307
- for (int y : pre) {
308
- cur. add(x & y);
309
- }
310
- cur. add(x);
311
- for (int y : cur) {
312
- ans = Math . min(ans, Math . abs(y - k));
313
- }
314
- pre = cur;
315
- }
316
- return ans;
317
- }
318
- }
95
+
319
96
```
320
97
321
98
#### C++
322
99
323
100
``` cpp
324
- class Solution {
325
- public:
326
- int minimumDifference(vector<int >& nums, int k) {
327
- int ans = abs(nums[ 0] - k);
328
- unordered_set<int > pre;
329
- pre.insert(nums[ 0] );
330
- for (int x : nums) {
331
- unordered_set<int > cur;
332
- cur.insert(x);
333
- for (int y : pre) {
334
- cur.insert(x & y);
335
- }
336
- for (int y : cur) {
337
- ans = min(ans, abs(y - k));
338
- }
339
- pre = move(cur);
340
- }
341
- return ans;
342
- }
343
- };
101
+
344
102
```
345
103
346
104
#### Go
347
105
348
106
``` go
349
- func minimumDifference(nums []int, k int) int {
350
- ans := abs(nums[0] - k)
351
- pre := map[int]bool{nums[0]: true}
352
- for _, x := range nums {
353
- cur := map[int]bool{x: true}
354
- for y := range pre {
355
- cur[x&y] = true
356
- }
357
- for y := range cur {
358
- ans = min(ans, abs(y-k))
359
- }
360
- pre = cur
361
- }
362
- return ans
363
- }
364
-
365
- func abs(x int) int {
366
- if x < 0 {
367
- return -x
368
- }
369
- return x
370
- }
371
- ```
372
107
373
- #### TypeScript
374
-
375
- ``` ts
376
- function minimumDifference(nums : number [], k : number ): number {
377
- let ans = Math .abs (nums [0 ] - k );
378
- let pre = new Set <number >();
379
- pre .add (nums [0 ]);
380
- for (const x of nums ) {
381
- const cur = new Set <number >();
382
- cur .add (x );
383
- for (const y of pre ) {
384
- cur .add (x & y );
385
- }
386
- for (const y of cur ) {
387
- ans = Math .min (ans , Math .abs (y - k ));
388
- }
389
- pre = cur ;
390
- }
391
- return ans ;
392
- }
393
108
```
394
109
395
110
<!-- tabs:end -->
0 commit comments