Problem
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.
Examples
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`.
Solution
Method 1 - Sliding Window
Using a strategy of managing the window elements, we can use two pointers to keep track of the current window.
To find the minimum length special subarray ending at index end
, we consider our current window [0, end]
(both inclusive) and calculate its bitwise OR based on a 32-bit array and a result num
.
If num
is less than k
, we expand the window by including the next element nums[end + 1]
. We continue this process until we find a special subarray where num
is at least k
. At this point, we have a candidate for the answer.
Next, we attempt to minimise the length by shrinking the window from the left side while maintaining the special condition num >= k
.
Once shrinking the window causes the special condition to be false (num
becomes less than k
), we remember that the previous window [start', end']
was valid and found a possible answer end' - start' + 1
.
Then, for finding the special subarray ending at index end' + 1
, we start from start' + 1
instead of completely restarting. Since we have already found a possible answer of length end' - start' + 1
, we only consider shorter lengths moving forward.
This technique leverages two pointers for an efficient sliding window approach.
Code
Java
class Solution {
public int minimumSubarrayLength(int[] nums, int k) {
int n = nums.length;
int ans = n + 1;
int[] bits = new int[32];
for (int start = 0, end = 0; end < n; end++) {
update(bits, nums[end], 1); // Insert nums[end] into the window
while (start <= end && bitsToNum(bits) >= k) {
ans = Math.min(ans, end - start + 1);
update(bits, nums[start++], -1); // Remove nums[start] from the window
}
}
return ans != n + 1 ? ans : -1;
}
private void update(int[] bits, int x, int change) {
// Insert or remove an element from the window. Time complexity: O(32)
for (int i = 0; i < 32; i++) {
if (((x >> i) & 1) != 0) {
bits[i] += change;
}
}
}
private int bitsToNum(int[] bits) {
// Convert the 32-size bits array to an integer. Time complexity: O(32)
int res = 0;
for (int i = 0; i < 32; i++) {
if (bits[i] != 0) {
res |= 1 << i;
}
}
return res;
}
}
Python
class Solution:
def minimum_subarray_length(self, nums: List[int], k: int) -> int:
n = len(nums)
ans = n + 1
bits = [0] * 32
def update(bits: List[int], x: int, change: int) -> None:
# Insert or remove an element from the window. Time complexity: O(32)
for i in range(32):
if (x >> i) & 1 != 0:
bits[i] += change
def bits_to_num(bits: List[int]) -> int:
# Convert the 32-size bits array to an integer. Time complexity: O(32)
res = 0
for i in range(32):
if bits[i] != 0:
res |= 1 << i
return res
start = 0
for end in range(n):
update(bits, nums[end], 1) # Insert nums[end] into the window
while start <= end and bits_to_num(bits) >= k:
ans = min(ans, end - start + 1)
update(bits, nums[start], -1) # Remove nums[start] from the window
start += 1
return ans if ans != n + 1 else -1
Complexity
- ⏰ Time complexity:
O(n)
,- The primary loop runs from
end = 0
toend = n-1
, which isO(n)
. - The
update(bits, nums[end], 1)
andupdate(bits, nums[start], -1)
each have a complexity ofO(32)
because the loop withinupdate
runs for a fixed number of 32 iterations (since we are dealing with 32-bit integers). - In the worst-case scenario, the
start
pointer can be incremented up ton
times. Given that each increment includes a call tobits_to_num(bits)
, which runs inO(32)
, this can happenn
times in total, leading to an additive term ofO(32n)
.
- The primary loop runs from
- 🧺 Space complexity:
O(1)