滑动窗口+位运算

Problem:

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

思路

终究还是用到了滑动窗口,暴力枚举在上一题点击查看

Code

class Solution {
    public int minimumSubarrayLength(int[] nums, int k) {
        int n = nums.length;
		//用数组去模拟当前或的结果的各位对应1的个数,依据题目范围,30足以模拟
        int[] bits = new int[30];
        int res = Integer.MAX_VALUE;
		//滑动窗口,right一点一点向右移动,直到满足题目中“特别”的要求
        for (int left = 0, right = 0; right < n; right++) {
			//更新各位1的个数
            for (int i = 0; i < 30; i++) {
                bits[i] += (nums[right] >> i) & 1;
            }
			//满足要求后,及时维护res结果,同时left左移查看时候用更短的数组,指导不符合要求,就继续外层for循环
            while (left <= right && calc(bits) >= k) {
                res = Math.min(res, right - left + 1);
				//更新各位1的个数
                for (int i = 0; i < 30; i++) {
                    bits[i] -= (nums[left] >> i) & 1;
                }
                left++;
            }
        }

        return res == Integer.MAX_VALUE ? -1 : res;
    }
	//计算对应数值
    private int calc(int[] bits) {
        int ans = 0;
        for (int i = 0; i < bits.length; i++) {
            if (bits[i] > 0) {
                ans |= 1 << i;
            }
        }
        return ans;
    }
}
posted @ 2025-01-17 23:13  韩熙隐ario  阅读(13)  评论(0)    收藏  举报