• 10.Find All Anagrams in a String(在一个字符串中发现所有的目标串排列)


    Level:

      Easy

    题目描述:

    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 sand 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".
    

    思路分析:

      知识点:滑动窗口

      关键点一:像这种找子串的可以使用滑动窗口Sliding Window来做。这个窗口由left和right来约束[left,right]这个闭区间,刚开始知识left=right=0,然后left不变,right不断增长,直到到达某个值,left和right一起增长,这样就实现了窗口的创建和向下滑动。

      关键点二:对于p中出现的字符以及次数需要记下来。可以使用一个数组ascaiiNums,长度为256,是因为ascaii一共只有256个,初始化的值表示角标对应的ascaii字符在p中出现的次数,那么没有出现过的就是0.之后如果s中出现过该字符,那么数组对应位置的值就减一。如果减之后的值大于等于0,就说明p中该字符出现了一次,这时p中未出现的字符数量count就减一。之所以要判断是>=0,是因为如果数组中原来的值是0(说明p中没有出现),那么减一后就成了负的,这种情况下p中剩下未出现的字符的count数值保持不变。如果count的值为0,说明p中的字符全出现了,找到一个符合条件的子串,left就是子串的首地址。之后要向右滑动窗口,移动的方法是left++,right++,更新p中未出现的字符个数count。

    代码:

    public class Solution{
        public List<Integer>findAnagrams(String s,String p){
            ArrayList<Integer>res=new ArrayList<>();
            if(s==null||p==null||p.length()>s.length())
                return res;
            int []map=new int [256];  //记录p中出现的元素
            for(char c:p.toCharArray())
                map[c]++;              //以c的Ascall为下标的值加一,其余没出现的都为0;
            int count=p.length(); //记录p中还未出现的字符个数
            int left=0;    //窗口左指针
            int right=0;   //窗口右指针
                while(right<s.length()){
                    char ch=s.charAt(right);
                    map[ch]--;
                    if(map[ch]>=0)  //证明ch是p中的字符
                        count--;    //p中未出现的个数减一
                    if(right-left+1==p.length()){
                        if(count==0) //说明p中的字符都已经出现
                            res.add(left);
                        char ch1=s.charAt(left);
                        map[ch1]++;
                        if(map[ch1]>0)//证明当前窗口最左边的值在p中存在,那么由于窗口要向下滑动一位,会舍弃该值,则count的数目就应该加1
                            count++;
                        left++;//窗口向下滑动
                        right++;
                    }else{
                        right++;
                    }
                }
            return res;
        }
    }
    
  • 相关阅读:
    【作业】第二周作业, 适合14级1/2班
    【作业】第二周作业,适合13级1/2/3班
    【组织】请13级1/2/3班,14级1/2班 将同学们的博客地址列个清单回复(按班级来)
    【组织】13级1、2、3班和14级1、2班 结对、分组情况请回帖
    【转】没什么能够阻挡,你对自由的向往
    【转】小屁孩, 懂个啥
    【转】远程结对编程实战:看看别人是怎么做的
    【转】看见成长的自己:斯坦福大学心理学教授徳韦克访谈
    【作业】第一周作业
    从std::thread::id取得int值id
  • 原文地址:https://www.cnblogs.com/yjxyy/p/10706168.html
Copyright © 2020-2023  润新知