995.k连续位的最小翻转次数

题目

在仅包含 0 和 1 的数组 A 中,一次 K 位翻转包括选择一个长度为 K 的(连续)子数组,同时将子数组中的每个 0 更改为 1,而每个 1 更改为 0。

返回所需的 K 位翻转的最小次数,以便数组没有值为 0 的元素。如果不可能,返回 -1。

示例

输入:A = [0,1,0], K = 1
输出:2
解释:先翻转 A[0],然后翻转 A[2]。

提示

  1. 1 <= A.length <= 30000
  2. 1 <= K <= A.length

题解

  1. 维持一个大小为K的窗口,左指针为0就反转并更新反转次数,,最后判断左指针到数组末尾是否包含0,若包含返回-1,否则返回反转次数(超时)
  2. 如何优化?
    1. 对于每一个大小为K的窗口,我们只需要判断该窗口的第一个元素是否为0,若为0就反转,否则就不反转
    2. 对于窗口内每一个元素,记录其之前的反转次数总和,并结合当前元素判断以该元素为首的窗口是否需要反转
    3. 反转次数为偶数情况下,元素不变,反转次数为奇数情况下,更换该元素的值
参考代码
class Solution {
    public int minKBitFlips(int[] A, int K) {
        int len = A.length;
        int[] diff = new int[len + 1]; // 两个相邻元素反转次数差值

        int res = 0;
        int count = 0;
        for(int i = 0; i < len; i++) {
            count += diff[i]; // 统计当前元素的反转次数
            // 反转次数+当前值若为偶数,表示A[i]为0,反转该窗口
            if((count + A[i]) % 2 == 0) {
                if(i + K > len) return -1;
                res++; // 更新反转次数
                // 差分数组若区间[i, i+K-1]反转了一次,则count++,diff[i+K]--
                count++; // 更新
                diff[i+K]--; // 更新
            }
        }
        return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值