算法11,滑动窗口,最大连续1的个数|||

是关于 "无重复字符的最长子串"问题​ 的滑动窗口解法。以下从题目分析、算法分析和代码编写三个方面进行总结:


题目分析

  • 问题 :给定一个字符串 s,找出其中不含有重复字符最长连续子串的长度。

  • 输入 :一个字符串 s

  • 输出:一个整数,表示最长无重复字符子串的长度。

  • 示例 :对于字符串 "abcabcbb",最长无重复字符子串是 "abc",长度为 3。

算法分析

您笔记中清晰地对比了两种思路:

  1. 暴力枚举 + 哈希表判断重复

    • 思路:枚举所有可能的子串(通过双重循环),对于每个子串,使用哈希表判断其中是否有重复字符。

    • 缺点:时间复杂度为 O(n²) 或 O(n³),效率低。

  2. 滑动窗口(双指针)法(最优解)

    • 核心思想 :利用两个同向移动的指针 leftright构成一个窗口,表示当前考察的子串。通过动态调整窗口边界,确保窗口内始终无重复字符,同时记录最大窗口长度。

    • 步骤

      1. 初始化left = 0, right = 0, 一个哈希集合 set用于存储窗口内的字符,maxLen = 0

      2. 进窗口 :将 s[right]加入集合 set,然后 right右移。

      3. 判断与去重 :如果加入后 sets[right-1]已存在(即出现重复),则不断从 set中移除 s[left]并将 left右移,直到重复被消除。

      4. 更新结果 :此时窗口内无重复,计算当前窗口长度 right - left,并更新 maxLen

      5. 重复步骤 2-4,直到 right到达字符串末尾。

    • 优化:可以使用数组(ASCII 码共128个字符)代替哈希集合,以提升速度。

    • 优点:每个字符最多被访问两次(进窗口和出窗口各一次),时间复杂度 O(n),空间复杂度 O(字符集大小)。

代码编写

以下是修正和完善您笔记中代码后的 Java 实现,提供两种版本:

版本一:使用 HashSet(易于理解)
复制代码
import java.util.HashSet;
import java.util.Set;

class Solution {
    public int lengthOfLongestSubstring(String s) {
        Set<Character> set = new HashSet<>();
        int left = 0, right = 0;
        int maxLen = 0;
        
        while (right < s.length()) {
            char c = s.charAt(right);
            // 如果字符已存在,则移动左指针直到重复字符被移除
            while (set.contains(c)) {
                set.remove(s.charAt(left));
                left++;
            }
            // 将当前字符加入集合
            set.add(c);
            // 更新最大长度
            maxLen = Math.max(maxLen, right - left + 1);
            right++;
        }
        return maxLen;
    }
}
版本二:使用数组(更高效)
复制代码
class Solution {
    public int lengthOfLongestSubstring(String s) {
        int[] hash = new int[128]; // ASCII 字符集
        int left = 0, right = 0;
        int maxLen = 0;
        
        while (right < s.length()) {
            char c = s.charAt(right);
            hash[c]++; // 进窗口
            // 判断:如果当前字符计数>1,说明有重复,移动左指针去重
            while (hash[c] > 1) {
                char leftChar = s.charAt(left);
                hash[leftChar]--; // 出窗口
                left++;
            }
            // 更新结果
            maxLen = Math.max(maxLen, right - left + 1);
            right++;
        }
        return maxLen;
    }
}

 public int longestOnes(int[] nums, int k) {
         int left=0;
        int count=0;
        int ret=0;
        for(int right=0;right<nums.length;right++){
            if(nums[right]==0){
                count++;
            }
            while(count>k){
                if(nums[left++]==0){
                    count--;
                }
            }
            ret=Math.max(ret,right-left+1);
        }
        return ret;
    }

代码说明

  • 进窗口:将右指针指向的字符加入集合或数组计数。

  • 判断与去重:如果加入后导致重复(集合已存在或数组计数>1),则持续移动左指针,从集合/数组中移除字符,直到重复消除。

  • 更新结果:每次窗口内无重复时,计算当前窗口长度并更新最大值。

  • 移动右指针:继续扩大窗口。

此解法是解决"无重复字符的最长子串"问题的标准滑动窗口方法,高效且易于理解。

相关推荐
倒头就睡的小比特2 天前
算法竞赛C++常用的STL
c++·算法
小羊没烦恼!2 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
猎头南楼2 天前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习
旖旎夜光2 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
wzdark2 天前
大规模并行计算中的负载均衡算法研究4
算法
Because_of_Her12 天前
并查集-听课笔记
笔记·算法·并查集
码流子2 天前
高速公路安全监测实践:碰撞监测预警+物联网底座,从感知到处置的闭环
大数据·人工智能·物联网·算法·架构
another heaven2 天前
【算法/C++ MD5算法能否逆解码?原理、C++实现与同类哈希算法对比】
c++·算法·哈希算法
wzdark2 天前
从算法设计模式看编程思维的抽象能力4
算法
2601_962218612 天前
万象生鲜系统称重自动多退少补算法解决生鲜非标品痛点
大数据·数据库·人工智能·python·算法