leetcode--Substring with Concatenation of All Words

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) in s 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;
    }	
}


你可能感兴趣的:(leetcode--Substring with Concatenation of All Words)