算法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),则持续移动左指针,从集合/数组中移除字符,直到重复消除。

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

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

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

相关推荐
地平线开发者12 分钟前
BEVdet模型解析
算法·自动驾驶
tudousisi22225 分钟前
P2758 编辑距离 题解复盘
算法
李可以量化37 分钟前
Tornado 从了解到精通(四)上:实战搭建 Web 应用与核心组件详解
算法
linux-hzh1 小时前
百日算法修炼 · Day 09
数据结构·算法·排序算法
DFT计算杂谈1 小时前
Janus单层Cr2SSe中的应变可调多压电效应与谷电子学
人工智能·算法·机器学习
今天AI了吗1 小时前
从 LLM 到 Agent Skill:把 AI 底层概念串起来
数据库·人工智能·sql·深度学习·神经网络·算法·机器学习
hanlin032 小时前
动态规划专练:力扣第1035、392题
算法·leetcode·动态规划
淡海水2 小时前
C#与常用数据结构源码剖析-全篇导览
开发语言·数据结构·unity·面试·职场和发展·c#
不正经学生2 小时前
C语言大小端字节序:内存里字节的排列顺序
c语言·开发语言·arm开发·c++·算法·c#
大模型探索者2 小时前
2026金融大模型训推平台选型指南:主流厂商横向对比与私有化落地
人工智能·算法·金融