美文网首页
findAnagrams(滑动窗口)

findAnagrams(滑动窗口)

作者: Ukuleler | 来源:发表于2019-05-07 17:14 被阅读0次

    Given a string s and a non-empty string p, find all the start indices of p's anagrams in s.

    Strings consists of lowercase English letters only and the length of both strings s and p will not be larger than 20,100.

    The order of output does not matter.

    Example 1:

    Input:
    s: "cbaebabacd" p: "abc"

    Output:
    [0, 6]

    Explanation:
    The substring with start index = 0 is "cba", which is an anagram of "abc".
    The substring with start index = 6 is "bac", which is an anagram of "abc".
    Example 2:

    Input:
    s: "abab" p: "ab"

    Output:
    [0, 1, 2]

    Explanation:
    The substring with start index = 0 is "ab", which is an anagram of "ab".
    The substring with start index = 1 is "ba", which is an anagram of "ab".
    The substring with start index = 2 is "ab", which is an anagram of "ab".

    Anagrams的意思是(字符都有,顺序可以不同的字符串,也可以说是异序)。
    这道题就是根据p在s中找有多少个Anagrams,返回一个数组。
    这道题的解题思路就是利用滑动窗口算法。

    1.将p转换进入一个hash表,value记录每一个key的出现次数。
    2.初始化两个指针left,right,两个指针构成一个窗口。
    3.初始化一个different(差异度),类型为int,长度为p.length,差异度代表了窗口内的字符串与p有多大差别,当different==0的时候代表该窗口内的字符串和p为Anagrams。
    4.窗口进行滑动,当right右移,判断s[right]是否在hash表内,若在则hash表-1,different-1。当left右移,判断s[left-1]是否在hash表内,若在则hash表+1,different+1。
    5.每次滑动判断different差异度是否0,若为0则遍历hash表,查看是否所有的value均为0(这步很重要,具体为什么要这样,自己敲一边就明白了)

    代码如下,时间复杂度为O(n),总结起来就是题不难,难点是思路,在不知道滑动窗口算法之前,简直想到爆炸

    package com.example.demo.leetcode;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    /**
     * @description:
     * @author: 王泽龙
     * @create: 2019-05-07 15:37
     **/
    public class findAnagrams {
        public static List<Integer> findAnagrams(String s, String p) {
            char[] cp = p.toCharArray();
            Map<Character, Integer> mp = new HashMap<>();
            for(int i=0;i<cp.length;i++){
                if(mp.containsKey(cp[i]))mp.put(cp[i],mp.get(cp[i])+1);
                else mp.put(cp[i],1);
            }
            char[] cs = s.toCharArray();
            int different = p.length();
            List<Integer> res = new ArrayList<>();
            int l=0,r=0;
            while(r<s.length()){
                if(r-l<=p.length()){
                    if(mp.containsKey(cs[r])){
                        different--;
                        mp.put(cs[r],mp.get(cs[r])-1);
                    }
                    r++;
                }
                if(r-l>p.length()){
                    l++;
                    if(mp.containsKey(cs[l-1])){
                        different++;
                        mp.put(cs[l-1],mp.get(cs[l-1])+1);
                    }
                }
                if(different==0){
                    boolean flag = true;
                    for(Map.Entry<Character, Integer> e: mp.entrySet()){
                        if(e.getValue()!=0){
                            flag=false;
                            break;
                        }
                    }
                    if(!flag)continue;
                    res.add(l);
                }
            }
            return res;
        }
    }
    
    

    相关文章

      网友评论

          本文标题:findAnagrams(滑动窗口)

          本文链接:https://www.haomeiwen.com/subject/oeryoqtx.html