【算法集训】基础算法:滑动窗口

文章介绍了如何利用快慢指针技巧解决三个不同问题:1.删除一个元素后全为1的最长子数组,2.找到最大连续1的个数,3.寻找最长的半重复子字符串。通过滑动指针快速遍历并更新状态,找到最优解。
摘要由CSDN通过智能技术生成

定义一个快慢指针,用于截取数组中某一段信息。同时可以改变快慢指针的值来获取结果,这个过程比较像滑动。

1493. 删掉一个元素以后全为 1 的最长子数组

  • 定义快慢指针
  • 快指针先走,如果到了第二个0上的时候。前面1的个数就是fast - slow - 1,但是为了后面的继续计算,需要将slow指针+1即可。
// 滑动窗口
int longestSubarray(int* nums, int numsSize) {
    // 定义快慢指针
    int slow = 0;
    int fast = -1;
    // 记录0的个数
    int zero = 0;
    // 最大长度
    int maxlen = 1;
    // 快指针走
    while(fast < numsSize - 1) {
        fast++;
        zero += !nums[fast];
        while(zero > 1) {
            zero -= !nums[slow];
            slow++;
        }
        if(fast - slow + 1 > maxlen) {
            maxlen = fast - slow + 1;
        }
    }
    return maxlen - 1;
}

1004. 最大连续1的个数 III

和上一题一样的,只不过将替换0的值增加为了k个。

int longestOnes(int* nums, int numsSize, int k) {
    // 定义快慢指针
    int slow = 0;
    int fast = -1;
    int zero = 0;  //记录0的个数
    int maxlen = 0; //最终的返回的最大长度
    // 快指针先走
    while(fast < numsSize - 1) {
        fast ++;
        zero += !nums[fast];
        while( zero > k) {
            zero -= !nums[slow];
            slow++;
        }
        if(maxlen < fast - slow + 1) {
            maxlen = fast - slow + 1;
        }
    }
    return maxlen;
}

2730. 找到最长的半重复子字符串

int longestSemiRepetitiveSubstring(char * s){
    int slow = 0;
    int fast = -1;
    int same = 0;
    int maxlen = 0;
    int len = strlen(s);
    // 快指针
    while(fast < len - 1) {
        fast++;
        // 如果快大于慢的话就可以看相邻的相等否了?
        if(fast - slow > 0) {
            // 如果相等则同样记录+1
            if(s[fast] == s[fast - 1]) {
                same++;
            }
            // 当大于1的时候就需要移动慢指针了
            while( same > 1 ) {
                if(s[slow] == s[slow + 1]) {
                    --same;
                }
                slow ++;
            }
        }
        if(fast - slow + 1 > maxlen) {
            maxlen = fast - slow + 1;
        }
    }
    return maxlen;
}
  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

子琦啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值