https://leetcode-cn.com/problems/max-consecutive-ones-iii/
这次虽然是一个中等题目,但是我自己写了出来。(竟然对自己的能力这么不自信吗!
所以,看到题目,老是感觉不知道如何转化为自己已经学过的知识,这是在哪个方面有欠缺呢?
题目,最大连续的1的个数,其中可以将固定数量的部分的0替换为1,只需枚举右区间的端点的大小,然后左边区间,按照要求,若0的数量已经超过某个数值,则向右滑动,本题实际上是滑动窗口问题。
代码:
class Solution {
public:
int longestOnes(vector<int>& A, int K) {
int k=K;
int left=0;
int cnt=0,res=0;
int n=A.size();
for(int i=0;i<n;i++){
if(A[i]==0) cnt++;
if(cnt<=k){
if(res<i-left+1) res=i-left+1;
}
while(cnt>k){
if(A[left++]==0) cnt--;
}
}
return res;
}
};
https://leetcode-cn.com/problems/minimum-number-of-k-consecutive-bit-flips/submissions/
求连续K位翻转的次数,使得元素值全部成为1。
贪心算法:
策略设置为,从前向后扫描,每次遇到一个0就将它后面的所有K位数字都翻转。
证明其正确性:
首先,由于翻转这一运算与其周围的所有元素无关,则可以按照任意次序进行翻转。所以顺序可以自我约定。
其次,反证法:
1、若需要翻转的第一位是0,但不是从前向后数的第一个数字0的话,那么将有,此0将永远无法变为1。
2、若是其之前的一个1的话,则其翻转后变成的0将永远无法变成1。
class Solution {
public:
int minKBitFlips(vector<int> &A, int K) {
int n=A.size();
vector<int> sum(n+1);
int total=0;
int ans=0;
for(int i=0;i<n;i++){
total+=sum[i];
if((A[i]+total)%2==0){
if(i+K>n) return -1;
total++;//总的翻转次数增加
ans++;//答案增加
sum[i+K]++;//i+k处的差分值增加
}
}
return ans;
}
};