Bootstrap

leetcode记录-340-至多包含 K 个不同字符的最长子串-双指针

340.至多包含 K 个不同字符的最长子串

在这里插入图片描述

思路

寻找字符串满足某个条件的子串,考虑双指针+滑动窗口思想(右指针一直前进,当遇到某个条件成立/不成立,更新左指针,然后右指针接着前进)。首先左右指针从0开始,右指针步进,用hashmap存储俩指针区间内每个字符最新出现的下标,当hashmap中元素个数大于要求的k时,证明元素多了,上一个子串寻找结束,更新左指针开始下一个子串寻找(舍弃目前区间内最右下标最小的舍弃,以获取最大长度),直到到最后。

代码

public class T340 {
    public int lengthOfLongestSubstringKDistinct(String s, int k) {
        //滑动窗口:右指针指向当前处理位置,左指针根据条件步进
        //字符串寻找各种类型的子串 均可以考虑是否可以滑动窗口,右指针一直前进,当遇到某个条件成立/不成立,更新左指针,然后右指针接着前进。
        //此题需要寻找字符串至多包含k个字符的最长子串,返回长度即可。
        //需要记录目前最长的,步进中不断更新,每次新的左指针变化前更新。
        //字符计数,最好用的还是hashmap,而此题每次更新串都是舍弃最早结束的字符。
        if (k==0||s.length()==0) return 0;
        int l=0,r=0;
        int len=0;
        Map<Character,Integer> map=new HashMap<>();
        while (r<s.length()){
            //先处理目前的r上的元素
            map.put(s.charAt(r),r);
            //当满足某个条件,需要暂时停下处理l指针
            if (map.size()>k){
                int min=Collections.min(map.values());
                map.remove(s.charAt(min));
                l=min+1;
            }
            //正常步进
            r++;
            //更新指标
            len=len>r-l?len:r-l;
        }
        return len;
    }
}

技巧

  1. 滑动窗口:右指针指向当前处理位置,当满足某个条件再步进左指针。书写代码时遵循,①先处理当前右指针元素,②然后如果满足某个条件,进行处理,左指针步进,③右指针步进,④更新指标。并且外层循环一般都是while (r<s.length())
  2. 字符计数,最好用的还是hashmap。虽然有时可以用128大小的int数组,下标表示ASCII码。
  3. Map<Character,Integer> map=new HashMap<>();
    ① HashMap是Map接口的主要实现类
    ② 使用哈希算法对键去重复,效率高,但无序
    ③ 提供key-value的存储和查询功能
    在这里插入图片描述
  4. Java Collections类操作:Collections.min(map.values());
    reverse(List list):对指定 List 集合元素进行逆向排序。
    sort(List list):根据元素的自然顺序对指定 List 集合的元素按升序进行排序。
    Object max(Collection coll):根据元素的自然顺序,返回给定集合中的最大元素。
    Object min(Collection coll):根据元素的自然顺序,返回给定集合中的最小元素。
    Object max(Collection coll, Comparator comp):根据 Comparator 指定的顺序,返回给定集合中的最大元素。
    int frequency(Collection c, Object o):返回指定集合中指定元素的出现次数。
    int indexOfSubList(List source, List target):返回子 List 对象在父 List 对象中第一次出现的位置索引;如果父 List 中没有出现这样的子 List,则返回 -1。
    int lastIndexOfSubList(List source, List target):返回子 List 对象在父 List 对象中最后一次出现的位置索引;如果父 List 中没有岀现这样的子 List,则返回 -1。

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;