K连续位的最小翻转次数——滑动窗口方法

题目链接

本题如果按照从左到右按个检查是否为0,挨个翻转K个长度,会超时。可以使用滑动窗口解决此题。

原理:位置为i的元素的值为0或1,会受到前K-1个元素的影响。
前K-1个元素如果翻转了偶数次,那么A[i]并不会改变;
前K-1个元素如果翻转了奇数次,那么A[i]会改变。
那么该元素是否需要翻转,只有两种情况:

1. A[i]为0,且前K-1个元素翻转了偶数次
2. A[i]为1,且前K-1个元素翻转了奇数次

得判断需要翻转的依据:翻转次数%2 == A[i] 那么需要翻转。

全部翻转为1的成功标志是:数组从头遍历到了结束。

失败的标志是:当元素下标加K已经超出数组长度,且该元素仍需要翻转,那么直接return -1。

此处用队列模拟滑动窗口,若遇到需要翻转的元素,则将该元素的下标入队,用以记录翻转的次数 即 队列的长度。

注:当队列的头元素(代表数组中该元素的下标)+K <= i时,说明这个元素的翻转并没有影响到A[i]的值,所以此时应当将其移除队列。


代码:

public int minKBitFlips(int[] A, int K) {
    
    
        Queue<Integer> queue = new LinkedList<>();
        int i = 0;
        int count = 0;
        while (i < A.length) {
    
    
            if (queue.size() % 2 == A[i]) {
    
    
                if (i + K > A.length) {
    
    
                    return -1;
                }
                queue.offer(i);
                count++;
            }
            i++;
            if (!queue.isEmpty() && queue.peek() + K <= i) {
    
    
                queue.poll();
            }
        }
        return count;
    }

猜你喜欢

转载自blog.csdn.net/qq_43665244/article/details/113851988