【leetcode详解】考试的最大困扰度(滑动窗口典例)

 实战总结:

  • sum += answerKey[right] == c; 经典操作,将判断语句转化为0, 1接收来计数
  • //大问题分解: 对'T'还是'F'做修改, 传对应字母为参数c
  • //滑动窗口: 遍历, 维护left& right指向 及 c 的个数, 更新
  • 不知从何下手写代码时:考虑先写好第一次的,然后以此为基础补充代码以适后续情况

题面:

解题感受: 思路总体好想, 实现略有挑战。

思路分析:

  • //rt不断向右遍历
  • //sum由rt,lf分别更新,记录二者所夹区间内的情况
  •         //遍历情况用0,1记录在sum中,作为更新lf的参考
  • //每一次循环都更新一次mx,保证不重不漏//这一步减少了太多分类讨论操作,详见文末代码

代码实现:

class Solution{
public:
	int maxConsecutiveAnswers(string answerKey, int k)
	{
		//大问题分解: 对'T'还是'F'做修改, 传参为c
		//滑动窗口: 遍历, 维护left& right指向 及 c的个数, 更新
		int len = answerKey.length(); 
		auto getcnt = [&](char c) -> int{
			int mx = 0;
            //rt不断向右遍历
            //sum由rt,lf分别更新,记录二者所夹区间内的情况
                //遍历情况用0,1记录在sum中,作为更新lf的参考
            //每一次循环都更新一次mx,保证不重不漏
			for(int lf=0, rt=0, sum=0; rt<len; rt++ )
			{
				//先写好第一次的
				sum += answerKey[rt] == c;
				//再补上后面的更新操作
				while(sum > k)//一直找到第k+1个
				{			  //以sum为依据,更新lf的值
					sum -= answerKey[lf++] == c;
				}
                mx = max(mx, rt-lf+1);//每一次循环都做一次更新,就避免了繁琐的分类讨论
			}
			return mx;			
		};
		return max(getcnt('F'), getcnt('T'));
	}
};

可以对比:由于最初没有想到每次循环时都要更新mx值,而修补出的含大量分类讨论的代码:(甚至最后依然不能AC)

class Solution {
public:
    int maxConsecutiveAnswers(string answerKey, int k) {
        auto getcnt = [&](char c) -> int
        {
			int pre = 0, mx = 0, cnt = 1, len = answerKey.length();
			int i=0;
			
			while(answerKey[i] != c && i < len) i++;
			if(answerKey[0] != c) pre = 0;
			else pre = i;//?
			// cout<<"t1 ";			
			if(i == len) return len;

			int j=i+1;
			//记忆化?
			while(cnt <= k && j < len){
				if(answerKey[j] == c) cnt++;
                j++;
			}
			if(j == len) return len;
            mx = max(mx, j-pre+1-1);
			while(j < len)
			{
				mx = max(mx, j-pre+1);
				
				i++, j++;
				pre = i;
				while(answerKey[i] != c && i < len) i++;
//				cout<<"t4 ";
				while(j < len && answerKey[j] != c) j++;
//				cout<<"t5 ";
			}
			return mx;
		};
        
		return max(getcnt('T'), getcnt('F'));    

    }
};

~希望对你有启发!~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值