findAnagrams(滑动窗口)

2019-05-07  本文已影响0人  Ukuleler

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;
    }
}

上一篇下一篇

猜你喜欢

热点阅读