<leetcode c++>995. K 连续位的最小翻转次数
作者:互联网
995. K 连续位的最小翻转次数
在仅包含 0
和 1
的数组 A
中,一次 K
位翻转包括选择一个长度为 K
的(连续)子数组,同时将子数组中的每个 0
更改为 1
,而每个 1
更改为 0
。
返回所需的 K
位翻转的最小次数,以便数组没有值为 0
的元素。如果不可能,返回 -1
。
示例 1:
输入:A = [0,1,0], K = 1 输出:2 解释:先翻转 A[0],然后翻转 A[2]。
示例 2:
输入:A = [1,1,0], K = 2 输出:-1 解释:无论我们怎样翻转大小为 2 的子数组,我们都不能使数组变为 [1,1,1]。
示例 3:
输入:A = [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]
提示:
1 <= A.length <= 30000
1 <= K <= A.length
这道题目咋一看完全没有思路,入手点是每个数字翻转两次就会变回原样,所以最小翻转的方案是唯一的。我们算出每个数字变成1所需要的翻转次数。
一个巧妙的方法是我们记录A[i] 和 A[i - 1]的翻转次数之差 diff [n], 这样在翻转 [l, r] 区间时, 我们只需要更新++diff[l] 和 --diff[r + 1]
class Solution { public: int minKBitFlips(vector<int>& A, int K) { //统计每个元素的翻转次数 //记录差值 int n = A.size(); vector<int> diff(n + 1, 0);//记录A[i] 和 A[i - 1]的翻转次数之差 int ans = 0, revCnt = 0; for(int i = 0; i < n; i++){ revCnt += diff[i]; if((A[i] + revCnt) % 2 == 0){ if(i + K > n) return -1; ++ans; ++revCnt; --diff[i + K]; } } return ans; } };
标签:995,int,次数,数组,diff,revCnt,翻转 来源: https://www.cnblogs.com/Dancing-Fairy/p/14415659.html