1. 程式人生 > >Leetcode演算法Java全解答--30. 與所有單詞相關聯的字串

Leetcode演算法Java全解答--30. 與所有單詞相關聯的字串

#Leetcode演算法Java全解答–30. 與所有單詞相關聯的字串

題目

給定一個字串 s 和一些長度相同的單詞 words。在 s 中找出可以恰好串聯 words 中所有單詞的子串的起始位置。

注意子串要與 words 中的單詞完全匹配,中間不能有其他字元,但不需要考慮 words 中單詞串聯的順序。

示例 1:

輸入:
  s = "barfoothefoobarman",
  words = ["foo","bar"]
輸出: [0,9]
解釋: 從索引 0 和 9 開始的子串分別是 "barfoor" 和 "foobar" 。
輸出的順序不重要, [9,0] 也是有效答案。
示例 2:

輸入:
  s = "wordgoodstudentgoodword",
  words = ["word","student"]
輸出: []

解答

public static List<Integer> findSubstring(String s, String[] words) {
    List<Integer> indexes=new ArrayList<>();
    if(words.length==0)
    return indexes;
    Map<String,Integer> counts=new HashMap<>();  //記錄陣列中每個單元所出現的個數        
    for(String word:words) {
    	counts.put(word, counts.getOrDefault(word, 0)+1);          //因為計數時map會自動負載掉已存在的相同key,所以呼叫getOrDefault(方法)
    }
    int n=s.length(),num=words.length,len=words[0].length();
    for(int i=0;i<n-num*len+1;i++) {                 //i是迭代字串的起始位置,當i>=n-num*len+1的時候  所剩字元已小於要求的字串 長度,結束
    	Map<String,Integer> seen=new HashMap<>();
    	int j=0;
    	while(j<num) {                                //該迴圈迭代尋找字串,i為起始索引
    		String word=s.substring(i+j*len, i+(j+1)*len);      //每次找的是從i開始,長度為len的一個字串
    		if(counts.containsKey(word)) {
    			seen.put(word, seen.getOrDefault(word, 0)+1);    //將迭代到的字串及個數放入Map中,與要求的Map進行對比
                if(seen.get(word)>counts.get(word))
                	break;
    		}else {
    			break;
    		}
    		j++;
    	}
    	if(j==num) {
    		indexes.add(i);
    	} 		
    }
    return indexes;  
  }