Welcome to Subscribe On Youtube
3097. Shortest Subarray With OR at Least K II
Description
You are given an array nums
of non-negative integers and an integer k
.
An array is called special if the bitwise OR
of all of its elements is at least k
.
Return the length of the shortest special non-empty subarray of nums
, or return -1
if no special subarray exists.
Example 1:
Input: nums = [1,2,3], k = 2
Output: 1
Explanation:
The subarray [3]
has OR
value of 3
. Hence, we return 1
.
Example 2:
Input: nums = [2,1,8], k = 10
Output: 3
Explanation:
The subarray [2,1,8]
has OR
value of 11
. Hence, we return 3
.
Example 3:
Input: nums = [1,2], k = 0
Output: 1
Explanation:
The subarray [1]
has OR
value of 1
. Hence, we return 1
.
Constraints:
1 <= nums.length <= 2 * 105
0 <= nums[i] <= 109
0 <= k <= 109
Solutions
Solution 1: Two Pointers + Counting
We can observe that if we fix the left endpoint of the subarray, as the right endpoint moves to the right, the bitwise OR value of the subarray will only increase, not decrease. Therefore, we can use the double pointers method to maintain a subarray that meets the conditions.
Specifically, we use two pointers $i$ and $j$ to represent the left and right endpoints of the subarray, respectively. Initially, both pointers are at the first element of the array. We use a variable $s$ to represent the bitwise OR value of the subarray, and initially, the value of $s$ is $0$. We also need to maintain an array $cnt$ of length $32$, which represents the occurrence times of each bit in the binary representation of each element in the subarray.
In each step, we move $j$ to the right by one position, and update $s$ and $cnt$. If the value of $s$ is greater than or equal to $k$, we continuously update the minimum length of the subarray and move $i$ to the right by one position until the value of $s$ is less than $k$. In this process, we also need to update $s$ and $cnt$.
Finally, we return the minimum length. If there is no subarray that meets the conditions, we return $-1$.
The time complexity is $O(n \times \log M)$ and the space complexity is $O(\log M)$, where $n$ and $M$ are the length of the array and the maximum value of the elements in the array, respectively.
-
class Solution { public int minimumSubarrayLength(int[] nums, int k) { int n = nums.length; int[] cnt = new int[32]; int ans = n + 1; for (int i = 0, j = 0, s = 0; j < n; ++j) { s |= nums[j]; for (int h = 0; h < 32; ++h) { if ((nums[j] >> h & 1) == 1) { ++cnt[h]; } } for (; s >= k && i <= j; ++i) { ans = Math.min(ans, j - i + 1); for (int h = 0; h < 32; ++h) { if ((nums[i] >> h & 1) == 1) { if (--cnt[h] == 0) { s ^= 1 << h; } } } } } return ans > n ? -1 : ans; } }
-
class Solution { public: int minimumSubarrayLength(vector<int>& nums, int k) { int n = nums.size(); int cnt[32]{}; int ans = n + 1; for (int i = 0, j = 0, s = 0; j < n; ++j) { s |= nums[j]; for (int h = 0; h < 32; ++h) { if ((nums[j] >> h & 1) == 1) { ++cnt[h]; } } for (; s >= k && i <= j; ++i) { ans = min(ans, j - i + 1); for (int h = 0; h < 32; ++h) { if ((nums[i] >> h & 1) == 1) { if (--cnt[h] == 0) { s ^= 1 << h; } } } } } return ans > n ? -1 : ans; } };
-
class Solution: def minimumSubarrayLength(self, nums: List[int], k: int) -> int: n = len(nums) cnt = [0] * 32 ans = n + 1 s = i = 0 for j, x in enumerate(nums): s |= x for h in range(32): if x >> h & 1: cnt[h] += 1 while s >= k and i <= j: ans = min(ans, j - i + 1) y = nums[i] for h in range(32): if y >> h & 1: cnt[h] -= 1 if cnt[h] == 0: s ^= 1 << h i += 1 return -1 if ans > n else ans
-
func minimumSubarrayLength(nums []int, k int) int { n := len(nums) cnt := [32]int{} ans := n + 1 s, i := 0, 0 for j, x := range nums { s |= x for h := 0; h < 32; h++ { if x>>h&1 == 1 { cnt[h]++ } } for ; s >= k && i <= j; i++ { ans = min(ans, j-i+1) for h := 0; h < 32; h++ { if nums[i]>>h&1 == 1 { cnt[h]-- if cnt[h] == 0 { s ^= 1 << h } } } } } if ans == n+1 { return -1 } return ans }
-
function minimumSubarrayLength(nums: number[], k: number): number { const n = nums.length; let ans = n + 1; const cnt: number[] = new Array<number>(32).fill(0); for (let i = 0, j = 0, s = 0; j < n; ++j) { s |= nums[j]; for (let h = 0; h < 32; ++h) { if (((nums[j] >> h) & 1) === 1) { ++cnt[h]; } } for (; s >= k && i <= j; ++i) { ans = Math.min(ans, j - i + 1); for (let h = 0; h < 32; ++h) { if (((nums[i] >> h) & 1) === 1 && --cnt[h] === 0) { s ^= 1 << h; } } } } return ans === n + 1 ? -1 : ans; }