滑动窗口的方法解决一些String的查找问题

今天来介绍一种“滑动窗口”算法,可以用来解决一些子串查找问题

1.查找同字母异序词
题目描述:提供一个字符串s和一个非空字符串t,求出字符串t在字符串s中的所有同字母异序词的起始位置
示例代码:

public class Solution {
    public List<Integer> findAnagrams(String s, String t) {
        List<Integer> result = new LinkedList<>();
        if(t.length()> s.length()) return result;
        Map<Character, Integer> map = new HashMap<>();
        for(char c : t.toCharArray()){
            map.put(c, map.getOrDefault(c, 0) + 1);
        }
        int counter = map.size();
        int begin = 0, end = 0;
        int head = 0;
        int len = Integer.MAX_VALUE;
        while(end < s.length()){
            char c = s.charAt(end);
            if( map.containsKey(c) ){
                map.put(c, map.get(c)-1);
                if(map.get(c) == 0) counter--;
            }
            end++;
            while(counter == 0){
                char tempc = s.charAt(begin);
                if(map.containsKey(tempc)){
                    map.put(tempc, map.get(tempc) + 1);
                    if(map.get(tempc) > 0){
                        counter++;
                    }
                }
                if(end-begin == t.length()){
                    result.add(begin);
                }
                begin++;
            }
        }
        return result;
    }
}

2.查找最长不重复子串
题目描述:给出一个字符串,求出这个字符串中最长不重复子串的长度

Given "abcabcbb", the answer is "abc", which the length is 3.
Given "bbbbb", the answer is "b", with the length of 1.
Given "pwwkew", the answer is "wke", with the length of 3. 

示例代码:

public class Solution {
    public int lengthOfLongestSubstring(String s) {
        Map<Character, Integer> map = new HashMap<>();
        int begin = 0, end = 0, counter = 0, d = 0;

        while (end < s.length()) {
            char c = s.charAt(end);
            map.put(c, map.getOrDefault(c, 0) + 1);
            if(map.get(c) > 1) counter++;
            end++;
            while (counter > 0) {
                char charTemp = s.charAt(begin);
                if (map.get(charTemp) > 1) counter--;
                map.put(charTemp, map.get(charTemp)-1);
                begin++;
            }
            d = Math.max(d, end - begin);
        }
        return d;
    }
}

3.同类问题的解决思路:

public class Solution {
        public List<Integer> slidingWindowTemplateByHarryChaoyangHe(String s, String t) {
            //定义一个list来存储结果
            List<Integer> result = new LinkedList<>();
            if(t.length()> s.length()) return result;

            //用到的数据结构主要是hashMap,用来存放目标子串中的字符
            //(K, V) = (Character, Frequence of the Characters)
            Map<Character, Integer> map = new HashMap<>();
            for(char c : t.toCharArray()){
                map.put(c, map.getOrDefault(c, 0) + 1);
            }

            int counter = map.size();//值必须是map的size,这样可以保证重复的字符不会重复记录

            //begin和end指针,共同确定滑动窗口的位置
            int begin = 0, end = 0;

            //来记录结果字符串的长度,先定义为最大整数
            int len = Integer.MAX_VALUE;

            //遍历源字符串s,循环条件:end < s.length();
            while(end < s.length()){

                char c = s.charAt(end);

                if( map.containsKey(c) ){
                    map.put(c, map.get(c)-1);
                    if(map.get(c) == 0) counter--;//通过计算counter的值来记录状态
                }
                end++;

                while(counter == 0 /*这里的判断条件要根据题目需求来定*/){

                    char tempc = s.charAt(begin);
                    if(map.containsKey(tempc)){//恢复map中的值和counter的值,以便进行下一个窗口的判断
                        map.put(tempc, map.get(tempc) + 1);
                        if(map.get(tempc) > 0) counter++;
                    }

                    /*存储,更新结果,这里具体操作根据题目而定*/
                    begin++;
                }
            }
            return result;
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值