算法题解之滑动窗口

Substring with Concatenation of All Words

寻找所有词连接的子串

思路:由于该字串是所有词典中的词连接的,所以该字串长度固定。因此本题可以看作一个滑动窗口的题。为了去除重复工作,每次滑动一个单词的长度,因此起始位置就有n种(n为单词长度)。每种起始位置的滑动策略如下:

   如果当前窗口满足条件,则窗口只往后移动一个单词,并且下一次只检查最后一个单词(中间的单词肯定满足条件)。

     如果当前窗口不满足条件,则有两种情况:

   1.当前窗口内不满足条件的第一个单词不存在于词典中,则下一个窗口就直接滑到这个单词的下一个单词;

   2.当前窗口内不满足条件的第一个单词存在于词典中,但是这个单词已经被前面用完了,则下一个窗口只往后移动一个单词,并且下一次之间从这个单词开始检查。

 1 public class Solution {
 2     public List<Integer> findSubstring(String s, String[] words) {
 3         List<Integer> res = new ArrayList<Integer>();
 4         int m = words.length;
 5         int n = words[0].length();
 6         Map<String, Integer> map = new HashMap<String, Integer>();
 7         for (String word : words) {
 8             if (map.containsKey(word)) {
 9                 map.put(word, map.get(word) + 1);
10             } else {
11                 map.put(word, 1);
12             }
13         }
14         for (int p = 0; p <= n - 1; p++) {
15             int start = p;
16             while (start + n * m - 1 < s.length()) {
17                 int i = 1;
18                 boolean moveOneWord = true;
19                 Map<String, Integer> copy = new HashMap<String, Integer>(map);
20                 while (moveOneWord && start + n * m - 1 < s.length()) {
21                     for(; i <= m; i++) {
22                         String cut = s.substring(start + (i - 1) * n, start + i * n);
23                         if (copy.containsKey(cut)) {
24                             if (copy.get(cut) == 0) {
25                                 moveOneWord = true;
26                                 break;
27                             } else {
28                                 copy.put(cut, copy.get(cut) - 1);
29                             }
30                         } else {
31                             start += i * n;
32                             i = 1;
33                             moveOneWord = false;
34                             break;
35                         }
36                     }
37                     
38                     if (i == m + 1) {
39                         res.add(start);
40                         moveOneWord = true;
41                     }
42                     if (moveOneWord) {
43                         String firstword = s.substring(start, start + n);
44                         copy.put(firstword, copy.get(firstword) + 1);
45                         start += n;
46                         i--;
47                     }
48                 }
49             } 
50         }
51         return res;
52     }
53 }
View Code
原文地址:https://www.cnblogs.com/coldyan/p/6041158.html