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.
For example:
nums = [1,2,3], k = 2
. The subarray [3]
has an OR value of 3
. Hence, you should return 1
.nums = [2,1,8], k = 10
. The subarray [2,1,8]
has an OR value of 11
. Hence, you should return 3
.nums = [1,2], k = 0
. The subarray [1]
has an OR value of 1
. Hence, you should return 1
.Describe an efficient algorithm to solve this problem.
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach means we're going to examine every possible chunk of numbers in our list. We will go through each chunk and see if it satisfies our condition: that the combined value of the numbers in the chunk is big enough.
Here's how the algorithm would work step-by-step:
def shortest_subarray_with_or_at_least_k_brute_force(numbers, k):
shortest_length = float('inf')
for start_index in range(len(numbers)):
current_or = 0
for end_index in range(start_index, len(numbers)):
current_or |= numbers[end_index]
# Check if the current subarray's OR value is at least k
if current_or >= k:
current_length = end_index - start_index + 1
# Update shortest_length if current_length is shorter
shortest_length = min(shortest_length, current_length)
if shortest_length == float('inf'):
return -1
return shortest_length
The goal is to find the shortest possible chunk of numbers that, when combined using 'OR', reach a certain target value. Instead of checking every single chunk, we use a 'sliding window' to efficiently explore possible chunks, expanding and shrinking it as needed.
Here's how the algorithm would work step-by-step:
def shortest_subarray_with_or_at_least_k(numbers, target_or):
shortest_length = float('inf')
current_or = 0
window_start = 0
for window_end in range(len(numbers)):
current_or |= numbers[window_end]
# Shrink the window from the left if the current OR is at least the target.
while current_or >= target_or:
current_window_length = window_end - window_start + 1
# Update shortest length found so far
shortest_length = min(shortest_length, current_window_length)
# Remove the leftmost element from the window.
current_or ^= numbers[window_start]
window_start += 1
if shortest_length == float('inf'):
return -1
else:
return shortest_length
Case | How to Handle |
---|---|
Null or empty input array | Return -1 (or appropriate error value) immediately as there's no subarray to process. |
Array with a single element and K is greater than that element | Return -1 since a single element cannot satisfy the OR condition. |
All elements in the array are 0 and K is greater than 0 | Return -1 because the OR of any subarray will be 0, which is less than K. |
K is 0 | Return 1 if the array is not empty, as any single element subarray will have OR >= 0; special case if the array is empty, return -1. |
Integer overflow when calculating OR | In languages like Java/C++, be cautious of integer overflow, but OR operation should not overflow unless the integers themselves are already overflowed. |
Array contains large numbers such that the OR of all elements overflows | Handle potential overflow issues carefully; the problem description needs to constrain the max integer size, otherwise, a BigInteger solution is necessary. |
No subarray exists that satisfies the condition | Return -1 if, after iterating through all possible subarrays, none meet the condition OR >= K. |
Array contains negative numbers | The bitwise OR operation is well-defined for negative numbers; no special handling is required unless the problem statement explicitly forbids negative numbers. |