https://leetcode-cn.com/problems/minimum-number-of-k-consecutive-bit-flips/
本来hard难度的题本小白是直接放弃的,,但是某大佬说他看不懂?????嗯????俺来瞧瞧
其实这个题首先的思路应该是 模拟翻转 不过必然超时
对一整个区间进行操作其实我们应该想到差分数组的
//
//created by Arc on 2021/2/16
//
//p2853 of luogu
#include<iostream>
#include<vector>
#include <queue>
#include <algorithm>
using namespace std;
/*
* diff是一个差分数组,储存与前一位的翻转次数的差
* revCnt[i]是指第i位所需要翻转的次数
*
* diff[0]=revCnt[0];
* diff[i]=revCnt[i]-revCnt[i-1](i>0)
*
*且revCnt[i]=diff[0]+diff[1]+...+diff[i]
* 所以通过这个公式其实revCnt不需要储存,每次直接通过这个累加公式计算就好
*
*/
class Solution {
public:
int minKBitFlips(vector<int> &A, int K) {
int n = A.size();
vector<int> diff(n + 1);
int ans = 0, revCnt = 0;//ans:总的需要翻转次数 revCnt:当前位需要翻转的次数
for (int i = 0; i < n; ++i) {
revCnt += diff[i];
//累加diff求出当前位置需要翻转的次数revCnt
if ((A[i] + revCnt) % 2 == 0) {//判断是否需要翻转:(原来该位的数+当前位置需要翻转的次数)%2==0为需要
if (i + K > n) {//需要翻转但是超位数了为不可能实现
return -1;
}
//底下为可能实现
/*diff[i]++ diff[i+K]-- 维护差分和
* 由于diff[i]变了所以revCnt也应该相应加一
*/
diff[i]++;//这里可以不写,因为接下来也不会用到
++ans;
++revCnt;
--diff[i + K];
}
}
return ans;
}
};