LeetCode:3097. 或值至少为 K 的最短子数组 II(滑动窗口 Java)

目录

3097. 或值至少为 K 的最短子数组 II

题目描述:

实现代码与解析:

滑动窗口

原理思路:


3097. 或值至少为 K 的最短子数组 II

题目描述:

给你一个 非负 整数数组 nums 和一个整数 k 。如果一个数组中所有元素的按位或运算 OR 的值 至少 为 k ,那么我们称这个数组是 特别的 。请你返回 nums 中 最短特别非空 子数组的长度,如果特别子数组不存在,那么返回 -1 。

示例 1:

输入:nums = [1,2,3], k = 2

输出:1

解释:子数组 [3] 的按位 OR 值为 3 ,所以我们返回 1 。

示例 2:

输入:nums = [2,1,8], k = 10

输出:3

解释:子数组 [2,1,8] 的按位 OR 值为 11 ,所以我们返回 3 。

示例 3:

输入:nums = [1,2], k = 0

输出:1

解释:子数组 [1] 的按位 OR 值为 1 ,所以我们返回 1 。

提示:

  • 1 <= nums.length <= 2 * 105
  • 0 <= nums[i] <= 109
  • 0 <= k <= 109

实现代码与解析:

滑动窗口

class Solution {
    public int minimumSubarrayLength(int[] nums, int k) {
                
        int res = Integer.MAX_VALUE;
        int l = 0, r = 0;
        int cur = 0;
        int n = nums.length;
        int tmp = 0;
        for (; r < n; r++) {
            cur |= nums[r];
            while (l <= r && (nums[l] | cur) >= k) {
                res = Math.min(res, r - l + 1);
                l++;
                if (tmp < l) {
                    for (int i = r - 1; i >= l; i--) {
                        nums[i] |= nums[i + 1];
                    }
                    tmp = r;
                    cur = 0;
                }

            }
        }
        return res == Integer.MAX_VALUE ? -1 : res;
    }
    
}

原理思路:

        因为|运算不可逆,所以不能像+-一样处理,l指针移动之后,需要获取当前当前子数组中的|运算值。用栈逆向存储一下,这里直接放在原数组里了。

你可能感兴趣的:(LeetCode,leetcode,java,算法)