Skip to content

3171. Find Subarray With Bitwise OR Closest to K 👍

  • Time: $O(n\log\max(\texttt{nums}))$
  • Space: $O(n)$
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution {
 public:
  // Similar to 1521. Find a Value of a Mysterious Function Closest to Target
  int minimumDifference(vector<int>& nums, int k) {
    int ans = INT_MAX;
    // all the values of subarrays that end in the previous number
    unordered_set<int> prev;

    for (const int num : nums) {
      unordered_set<int> next{num};
      // Extend each subarray that ends in the previous number. Due to
      // monotonicity of the OR operation, the size of `next` will be at most
      // num.bit_count() + 1.
      for (const int val : prev)
        next.insert(val | num);
      for (const int val : next)
        ans = min(ans, abs(k - val));
      prev = std::move(next);
    }

    return ans;
  }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
  // Similar to 1521. Find a Value of a Mysterious Function Closest to Target
  public int minimumDifference(int[] nums, int k) {
    int ans = Integer.MAX_VALUE;
    // all the values of subarrays that end in the previous number
    Set<Integer> prev = new HashSet<>();

    for (final int num : nums) {
      HashSet<Integer> next = new HashSet<>(Arrays.asList(num));
      // Extend each subarray that ends in the previous number. Due to
      // monotonicity of the OR operation, the size of `next` will be at most
      // Integer.bitCount(num) + 1.
      for (final int val : prev)
        next.add(val | num);
      for (final int val : next)
        ans = Math.min(ans, Math.abs(k - val));
      prev = next;
    }

    return ans;
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
class Solution:
  # Similar to 1521. Find a Value of a Mysterious Function Closest to Target
  def minimumDifference(self, nums: list[int], k: int) -> int:
    ans = math.inf
    dp = set()  # all the values of subarrays that end in the current number

    for num in nums:
      # Extend each subarray that ends in the dpious number. Due to
      # monotonicity of the OR operation, the size of `next_set` will be at most
      # bin(num).count('1') + 1.
      dp = {num} | {val | num for val in dp}
      ans = min(ans, min(abs(k - val) for val in dp))

    return ans