• 算法通关村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);

    代码

    1. /**
    2. * Hash存储
    3. * @param s
    4. * @return
    5. */
    6. public static int lengthOfLongestSubtring2(String s){
    7. if (s.length() == 0) return 0;
    8. HashMap map = new HashMap<>();
    9. int max = 0;
    10. int left = 0;
    11. for (int right = 0; right < s.length(); right++) {
    12. if (map.containsKey(s.charAt(right))){
    13. left = Math.max(left,map.get(s.charAt(right)) + 1);
    14. }
    15. map.put(s.charAt(right),right);
    16. max = Math.max(max,right - left + 1);
    17. }
    18. return max;
    19. }

    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.

    代码中也有注释。

    代码

    1. public int lengthOfLongestSubstringTwoDIstinct(String s){
    2. if (s.length() < 3){
    3. return s.length();
    4. }
    5. int left = 0, right = 0;
    6. HashMap hashmap = new HashMap<>();
    7. int maxLen = 2;
    8. while (right < s.length()){
    9. if (hashmap.size() < 3){
    10. //map大小于3的时候,右指针向前移动,并更新已有字符最新的下表索引
    11. hashmap.put(s.charAt(right),right++);
    12. }
    13. //如果大小达到了3个
    14. if (hashmap.size() == 3){
    15. //删除最左侧的位置,最小的索引
    16. int del_idx = Collections.min(hashmap.values());
    17. hashmap.remove(s.charAt(del_idx));
    18. //窗口left的新位置
    19. left = del_idx + 1;
    20. }
    21. maxLen = Math.max(maxLen,right - left);
    22. }
    23. return maxLen;
    24. }

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

    题目

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

    思路

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

    代码

    1. public int lengthOfLongestSubstringKDIstinct(String s, int k){
    2. if (s.length() < k + 1){
    3. return s.length();
    4. }
    5. int left = 0, right = 0;
    6. HashMap map = new HashMap<>();
    7. int maxLen = k;
    8. while (right < s.length()){
    9. if (map.size() < k + 1){
    10. map.put(s.charAt(right), right++);
    11. }
    12. //如果大小达到了k,删除最左侧的
    13. if (map.size() == k + 1){
    14. int del_idx = Collections.min(map.values());
    15. map.remove(s.charAt(del_idx));
    16. left = del_idx + 1;
    17. }
    18. maxLen = Math.max(maxLen, right - left);
    19. }
    20. return maxLen;
    21. }

  • 相关阅读:
    进程间通信学习笔记
    【练习八 结构体(强化)编程题7. 公共钥匙盒】
    stack 相关题目 day 1
    基于 Python 中的值对计数器进行排序
    离散化模板
    养老院IPTV数字电视系统方案-养老公寓康养社区IPTV电视系统建设指南
    ES6基础总结(上)
    全面升级 | 两行代码,轻松搞定登录系统
    synchronized原理-字节码分析、对象内存结构、锁升级过程、Monitor
    Asp .Net Core 系列:Asp .Net Core 集成 Newtonsoft.Json
  • 原文地址:https://blog.csdn.net/m0_54138535/article/details/132661192