leetcode--Substring with Concatenation of All Words

来源:互联网 发布:淘宝助理没有安能物流 编辑:程序博客网 时间:2024/06/07 01:04

You are given a string, s, and a list of words, words, that are all of the same length. Find all starting indices of substring(s) ins that is a concatenation of each word in words exactly once and without any intervening characters.

For example, given:
s: "barfoothefoobarman"
words: ["foo", "bar"]

You should return the indices: [0,9].
(order does not matter).

思路:思路是使用滑动窗口来解决问题,首先要找到起始位置,因为题目例如“barfoothefoobarman”,["foo","bar"],要查找的字符串长度为3,那么假设从开头开始找,我们就按顺序找bar,foo,the,foo,bar,man,然后在从第二个开始找,arf,oot,hef,oob,arm,再从三个开始找,rfo,oth,efo,oba,rma,然后从第四个开始找,这是我们就会发现其实已经重复了,也就是从第一个开始找,已经包含了从第四个开始找的内容,所以我们会在代码中看到,最外层循环是3

然后每次循环是这样的,我们从起始位置,每次获取三个字符作为字符串,并且检验是否是我们要找的字符串,如果是,修改记录(说明找到了一个);如果不是,就要移动起始位置

就算我们找到了要找的一个字符串,它也可能是多余的,例如我们之前已经找到了foo,但是下一个还是foo,超出的我们要找的foo数目,这时就要移动其实位置,直到记录中的foo数目小于或等于要找的数目,再重新设置其实位置

当我们找齐了所以字符串,保存当前起始位置,然后再去除窗口的第一个记录,接着继续向右查找

public class Solution {    public List<Integer> findSubstring(String s, String[] words) {    List<Integer> result = new ArrayList<Integer>();    if(s==null || s.length()==0 || words==null || words.length==0)              return result;    Map<String,Integer> map = new HashMap<String,Integer>();         for(int i=0;i<words.length;i++){//初始化map        if(map.containsKey(words[i])){        map.put(words[i],map.get(words[i])+1);        }else{        map.put(words[i],1);        }                }               int word_size = words[0].length();                for(int i=0;i<word_size;i++){//注意,这里循环字符串长度即可        Map<String,Integer> findmap = new HashMap<String,Integer>();//用于记录当前字符串收集情况        int count = 0;//当前收集个数        int start = i;//当前起始index        for(int j=i;j<=s.length()-word_size;j+=word_size){//从当前起始index开始到能容纳一个字符串的位置,j表示字符串的起始坐标              String word = s.substring(j, j+word_size);//获取当前字符串                if(map.containsKey(word)){                if(!findmap.containsKey(word)){        findmap.put(word, 1);                }else{                findmap.put(word, findmap.get(word)+1);                }        if(findmap.get(word)>map.get(word)){//滑动窗口                while(findmap.get(word)>map.get(word)){//移动窗口直到消除多出来的字符串        String str = s.substring(start, start+word_size);        if(findmap.containsKey(str)){        findmap.put(str, findmap.get(str)-1);        if(findmap.get(str)<map.get(str))                                      count--;        }        start += word_size;//重定位起始位置        }        }else{        count++;        }        if(count==words.length){//找齐                result.add(start);            String temp = s.substring(start,start+word_size);                          if(findmap.containsKey(temp))//去除第一个                              findmap.put(temp,findmap.get(temp)-1);                        count--;//数目减少1                        start += word_size;//重定位起始位置            }        }else{//如果不是要找的字符串        count = 0;        start = j+word_size;//重定位起始位置        findmap.clear();        }                }                    }                //System.err.println(result);        return result;    }}


0 0
原创粉丝点击