算法通关村16关 | 滑动窗口最长字串专题

1. 最长字串专题

1.1 无重复字符的最长字串

题目

LeetCode3 给定一个字符串s,请你找出其中不含有重复字符的最长字串的长度。

思路

找最长字串,需要知道所有无重复字串的首和尾,找出其中最长的,最少两个指针才可以完成,可以使用滑动窗口思想,结合Map使用。

用map的key表示当前正在访问的字符串,value是其下标的索引值,每访问一个新元素,就将其value更新为对应的索引值。

left的位置需要处理,当第二次遇到a的时候,需要将left的位置向前移动一位,然后再更新a的value,用代码表示left的位置map.get('a') + 1 ,优化后是map.get(s.chat(i)) + 1,

需要考虑特殊情况, 例如abba,第二次访问b时候,left=map.get('b') + 1=2,再访问第二个a的时候 ,因为a重复了,所以left=map.get('a') + 1=1,left后退了,我们应该保持left在2的基础上继续向前,或者保持不变 ,也就是:left=Math.max(left,map.get(s.charAt(i)) + 1);

代码

java 复制代码
    /**
     * Hash存储
     * @param s
     * @return
     */
    public static int lengthOfLongestSubtring2(String s){
        if (s.length() == 0) return 0;
        HashMap<Character, Integer> map = new HashMap<>();
        int max = 0;
        int left = 0;
        for (int right = 0; right < s.length(); right++) {
            if (map.containsKey(s.charAt(right))){
                left = Math.max(left,map.get(s.charAt(right)) + 1);
            }
            map.put(s.charAt(right),right);
            max = Math.max(max,right - left + 1);
        }
        return max;
    }

1.2 最多包含两个不同字符的最长字串

题目

给定一个字符串s,找出至多包含两个不同字符的最长字串t,并返回该字串的长度,LeetCode159.

思路

类似于上题的方法,用left和right锁定一个窗口,一边移动一边分析,用map存储窗口中元素的个数,每次map中的key代表字符,value是最新字符的下标,

怎么保证只有两个不同字符?

当map.size=3的时候需要删除其中的最小value,也就是最左边的字符,左指针要移动的位置是删除位置索引+1。

del_idx = Collections.min(hashmap.values())

left = del_idx + 1.

代码中也有注释。

代码

java 复制代码
    public int lengthOfLongestSubstringTwoDIstinct(String s){
        if (s.length() < 3){
            return s.length();
        }
        int left = 0, right = 0;
        HashMap<Character, Integer> hashmap = new HashMap<>();
        int maxLen = 2;

        while (right < s.length()){
            if (hashmap.size() < 3){
                //map大小于3的时候,右指针向前移动,并更新已有字符最新的下表索引
                hashmap.put(s.charAt(right),right++);
            }
            //如果大小达到了3个
            if (hashmap.size() == 3){
                //删除最左侧的位置,最小的索引
                int del_idx = Collections.min(hashmap.values());
                hashmap.remove(s.charAt(del_idx));
                //窗口left的新位置
                left = del_idx + 1;
            }
            maxLen = Math.max(maxLen,right - left);
        }
        return maxLen;
    }

1.3 至多包含k个不同字符的最长字串。

题目

两个不同字符升级为k个不同字符,LeetCode340题,给定字符串,找出至多包含k个不同字符的最长字串T。

思路

与两个不同字符串一样,map的最大长度为k,

代码

java 复制代码
    public int lengthOfLongestSubstringKDIstinct(String s, int k){
        if (s.length() < k + 1){
            return s.length();
        }
        int left = 0, right = 0;
        HashMap<Character, Integer> map = new HashMap<>();
        int maxLen = k;
        while (right < s.length()){
            if (map.size() < k + 1){
                map.put(s.charAt(right), right++);
            }
            //如果大小达到了k,删除最左侧的
            if (map.size() == k + 1){
                int del_idx = Collections.min(map.values());
                map.remove(s.charAt(del_idx));
                left = del_idx + 1;
            }
            maxLen = Math.max(maxLen, right - left);
        }
        return maxLen;
    }
相关推荐
CoderYanger15 小时前
A.每日一题——1523. 在区间范围内统计奇数数目
java·数据结构·算法·leetcode·职场和发展
surtr115 小时前
Round 1019(div2) CD
数据结构·c++·算法·贪心算法·stl
Hcoco_me15 小时前
大模型面试题14:K-means聚类算法全解析(通用场景+深度拓展)
算法·kmeans·聚类
Jay200211115 小时前
【机器学习】30 基于内容的过滤算法
人工智能·算法·机器学习
冰西瓜60015 小时前
分治(二)算法设计与分析 国科大
数据结构·算法
小小晓.16 小时前
Pinely Round 2 (Div. 1 + Div. 2)
c++·算法
清风拂山岗 明月照大江16 小时前
简单文件 IO 示例:使用系统调用读写文件
开发语言·c++·算法
Hcoco_me16 小时前
大模型面试题15:DBSCAN聚类算法:步骤、缺陷及改进方向
算法·数据挖掘·聚类
AI绘画哇哒哒16 小时前
AI 智能体长期记忆系统架构设计与落地实践
人工智能·学习·算法·ai·程序员·产品经理·转行
加藤不太惠16 小时前
【无标题】
java·数据结构·算法