Find Subarray With Bitwise OR Closest to K
HardUpdated: Aug 2, 2025
Practice on:
Problem
You are given an array nums and an integer k. You need to find a subarray of nums such that the absolute difference between k and the bitwise
OR of the subarray elements is assmall as possible. In other words, select a subarray nums[l..r] such that |k - (nums[l] OR nums[l + 1] ... OR nums[r])| is minimum.
Return the minimum possible value of the absolute difference.
A subarray is a contiguous non-empty sequence of elements within an array.
Examples
Example 1
Input: nums = [1,2,4,5], k = 3
Output: 0
Explanation:
The subarray `nums[0..1]` has `OR` value 3, which gives the minimum absolute
difference `|3 - 3| = 0`.
Example 2
Input: nums = [1,3,1,3], k = 2
Output: 1
Explanation:
The subarray `nums[1..1]` has `OR` value 3, which gives the minimum absolute
difference `|3 - 2| = 1`.
Example 3
Input: nums = [1], k = 10
Output: 9
Explanation:
There is a single subarray with `OR` value 1, which gives the minimum absolute
difference `|10 - 1| = 9`.
Constraints
1 <= nums.length <= 10^51 <= nums[i] <= 10^91 <= k <= 10^9
Solution
Method 1 – Sliding Window with Set of ORs
Intuition
For each subarray, the bitwise OR can only increase or stay the same as we extend the subarray. We can use a set to keep all possible ORs ending at each position, and for each, check the absolute difference to k.
Approach
- Initialize a set to keep all possible ORs ending at the previous position.
- For each number in
nums, create a new set of ORs by OR-ing the current number with all ORs from the previous set, and also include the current number itself. - For each OR value, update the minimum absolute difference to
k. - Return the minimum difference found.
Code
C++
class Solution {
public:
int closestToK(vector<int>& nums, int k) {
int ans = INT_MAX;
unordered_set<int> prev;
for (int x : nums) {
unordered_set<int> cur = {x};
for (int v : prev) cur.insert(v | x);
for (int v : cur) ans = min(ans, abs(v - k));
prev = cur;
}
return ans;
}
};
Go
func closestToK(nums []int, k int) int {
ans := 1<<31 - 1
prev := map[int]struct{}{}
for _, x := range nums {
cur := map[int]struct{}{x: {}}
for v := range prev {
cur[v|x] = struct{}{}
}
for v := range cur {
if abs(v-k) < ans {
ans = abs(v-k)
}
}
prev = cur
}
return ans
}
func abs(x int) int { if x < 0 { return -x }; return x }
Java
class Solution {
public int closestToK(int[] nums, int k) {
int ans = Integer.MAX_VALUE;
Set<Integer> prev = new HashSet<>();
for (int x : nums) {
Set<Integer> cur = new HashSet<>();
cur.add(x);
for (int v : prev) cur.add(v | x);
for (int v : cur) ans = Math.min(ans, Math.abs(v - k));
prev = cur;
}
return ans;
}
}
Kotlin
class Solution {
fun closestToK(nums: IntArray, k: Int): Int {
var ans = Int.MAX_VALUE
var prev = mutableSetOf<Int>()
for (x in nums) {
val cur = mutableSetOf(x)
for (v in prev) cur.add(v or x)
for (v in cur) ans = minOf(ans, kotlin.math.abs(v - k))
prev = cur
}
return ans
}
}
Python
class Solution:
def closestToK(self, nums: list[int], k: int) -> int:
ans = float('inf')
prev = set()
for x in nums:
cur = {x}
for v in prev:
cur.add(v | x)
for v in cur:
ans = min(ans, abs(v - k))
prev = cur
return ans
Rust
impl Solution {
pub fn closest_to_k(nums: Vec<i32>, k: i32) -> i32 {
let mut ans = i32::MAX;
let mut prev = std::collections::HashSet::new();
for &x in &nums {
let mut cur = std::collections::HashSet::new();
cur.insert(x);
for &v in &prev { cur.insert(v | x); }
for &v in &cur { ans = ans.min((v - k).abs()); }
prev = cur;
}
ans
}
}
TypeScript
class Solution {
closestToK(nums: number[], k: number): number {
let ans = Infinity;
let prev = new Set<number>();
for (const x of nums) {
const cur = new Set<number>([x]);
for (const v of prev) cur.add(v | x);
for (const v of cur) ans = Math.min(ans, Math.abs(v - k));
prev = cur;
}
return ans;
}
}
Complexity
- ⏰ Time complexity:
O(n * W), wherenis the length ofnumsandWis the number of unique OR values per position (at most 32 for 32-bit integers). - 🧺 Space complexity:
O(W), for the set of OR values.