首页 > 其他分享 >【数据结构-差分】【hard】力扣995. K 连续位的最小翻转次数

【数据结构-差分】【hard】力扣995. K 连续位的最小翻转次数

时间:2024-09-21 23:48:13浏览次数:3  
标签:995 元素 nums ++ hard 力扣 数组 diff 翻转

给定一个二进制数组 nums 和一个整数 k 。

k位翻转 就是从 nums 中选择一个长度为 k 的 子数组 ,同时把子数组中的每一个 0 都改成 1 ,把子数组中的每一个 1 都改成 0 。

返回数组中不存在 0 所需的最小 k位翻转 次数。如果不可能,则返回 -1 。

子数组 是数组的 连续 部分。

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

示例 2:
输入:nums = [1,1,0], K = 2
输出:-1
解释:无论我们怎样翻转大小为 2 的子数组,我们都不能使数组变为 [1,1,1]。

示例 3:
输入:nums = [0,0,0,1,0,1,1,0], K = 3
输出:3
解释:
翻转 A[0],A[1],A[2]: A变成 [1,1,1,1,0,1,1,0]
翻转 A[4],A[5],A[6]: A变成 [1,1,1,1,1,0,0,0]
翻转 A[5],A[6],A[7]: A变成 [1,1,1,1,1,1,1,1]
在这里插入图片描述
差分

class Solution {
public:
    int minKBitFlips(vector<int>& nums, int k) {
        int n = nums.size();
        vector<int> diff(n+1);
        int s = 0, ans = 0;
        for(int i = 0; i < n; i++){
            //s是偶数的时候,翻转后还是原来元素,奇数时候才有效果。
            s += diff[i];
            if((nums[i] + s) % 2 == 0){
                s++;
                ans++;
                if(i+k > n){
                    return -1;
                }
                diff[i+k]--;
            }
        }
        return ans;
    }
};

这道题使用差分的思路是非常巧妙的方法。

首先我们定义差分的数组diff,整型s,s实际上就是某一个元素的翻转次数,整型ans用来储存总共翻转几次区间。

我们首先需要知道,比如当k=3的时候,我们翻转某一个元素,这时候会影响到这个元素及其后面两个元素。所以当翻转某一个元素的时候,我们就令s++,然后diff[i+k]--, 他由diff[i+k-1+1]化简。这时候这个元素及后面k-1个元素都会记录被反转。

当某个元素翻转s次后,如果是偶数,说明他受前面元素的翻转影响后,会是0。要注意的是,我们在判断某一个元素是否需要主动翻转的时候,是根据他受前面被动的翻转后是否为0来判断的。

每次主动翻转就s++,然后diff[i+k],从而影响这个元素及其后面的k-1个元素。

由于diff最多到diff(n)是合法的,所以当i+k>n的时候就返回-1。

标签:995,元素,nums,++,hard,力扣,数组,diff,翻转
From: https://blog.csdn.net/sjsjs11/article/details/142366315

相关文章

  • 【力扣 | SQL题 | 每日三题】力扣175, 176, 181
    1.力扣175:组合两个表1.1题目:表: Person+-------------+---------+|列名|类型|+-------------+---------+|PersonId|int||FirstName|varchar||LastName|varchar|+-------------+---------+personId是该表的主键(具有唯一......
  • 【数据结构与算法 | 灵神题单 | 栈基础篇】力扣1441, 844, 682
    1.力扣1441:用栈操作构建数组1.1题目:给你一个数组 target 和一个整数 n。每次迭代,需要从  list={1,2,3...,n} 中依次读取一个数字。请使用下述操作来构建目标数组 target :"Push":从 list 中读取一个新元素,并将其推入数组中。"Pop":删除数组中的最后一......
  • 力扣最热一百题——除自身以外数组的乘积
    目录题目链接:238.除自身以外数组的乘积-力扣(LeetCode)题目描述示例提示:解法一:左右数组(小型动态规划)实现思路Java写法:运行时间C++写法:运行时间时间复杂度以及空间复杂度总结题目链接:238.除自身以外数组的乘积-力扣(LeetCode)注:下述题目描述和示例均来自力扣......
  • 力扣最热一百题——搜索二维矩阵
    目录题目链接:240.搜索二维矩阵II-力扣(LeetCode)题目描述解法一:暴力不解释Java写法:运行时间C++写法:运行时间时间复杂度以及空间复杂度 解法二:利用自带的大小关系进行Z型走位Java写法:运行时间C++写法运行时间时间复杂度以及空间复杂度总结题目链接:240.......
  • 【力扣20】有效的括号
    20.有效的括号-力扣(LeetCode)括号序列压入栈中,遇到匹配的出栈,最后判断栈是否为空直接使用栈的数据结构stack。classSolution{public:boolisValid(strings){stack<char>stk;//初始化栈for(autoc:s){//入栈if(c=='......
  • 力扣题解2376
    大家好,欢迎来到无限大的频道。今日继续给大家带来力扣题解。题目描述(困难):统计特殊整数如果一个正整数每一个数位都是 互不相同 的,我们称它是 特殊整数 。给你一个 正 整数 n ,请你返回区间 [1,n] 之间特殊整数的数目。​解题思路:要计算区间([1,n])之间的......
  • 力扣188-买卖股票的最佳时机 IV(Java详细题解)
    题目链接:188.买卖股票的最佳时机IV-力扣(LeetCode)前情提要:本题是由123.买卖股票的最佳时机III-力扣(LeetCode)变形而来,123是只能买卖俩次股票,该题是只能买卖k次股票,我相信当你做完这道题或者看完我上道题的题解,那么写这道题会轻松一点。因为本人最近都来刷dp类的题......
  • 1,Python数分之Pandas训练,力扣,1783. 大满贯数量
    学习:知识的初次邂逅复习:知识的温故知新练习:知识的实践应用目录 一,原题力扣链接二,题干三,建表语句四,分析四,Pandas解答:五,验证六,总结 一,原题力扣链接.-力扣(LeetCode)二,题干表:Players+----------------+---------+|ColumnName|Type|+--------......
  • 【力扣刷题】2090.半径为k的子数组平均值(定长滑动窗口)
    题目:给你一个下标从 0 开始的数组 nums ,数组中有 n 个整数,另给你一个整数 k 。半径为k的子数组平均值 是指:nums 中一个以下标 i 为 中心 且 半径 为 k 的子数组中所有元素的平均值,即下标在 i-k 和 i+k 范围(含 i-k 和 i+k)内所有元素的平均......
  • 【力扣刷题】1232.缀点成线
    题目:给定一个数组 coordinates ,其中 coordinates[i]=[x,y] , [x,y] 表示横坐标为 x、纵坐标为 y 的点。请你来判断,这些点是否在该坐标系中属于同一条直线上。示例1:输入:coordinates=[[1,2],[2,3],[3,4],[4,5],[5,6],[6,7]]输出:true示例2: 输入:coordina......