[LeetCode] 30. Substring with Concatenation of All Words

Posted aaronliu1991

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[LeetCode] 30. Substring with Concatenation of All Words相关的知识,希望对你有一定的参考价值。

串联所有单词的子串。题意是给定一个字符串 s 和一些长度相同的单词 words。找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置。注意子串要与 words 中的单词完全匹配,中间不能有其他字符,但不需要考虑 words 中单词串联的顺序。例子,

Example 1:

Input:
  s = "barfoothefoobarman",
  words = ["foo","bar"]
Output: [0,9]
Explanation: Substrings starting at index 0 and 9 are "barfoo" and "foobar" respectively.
The output order does not matter, returning [9,0] is fine too.

Example 2:

Input:
  s = "wordgoodgoodgoodbestword",
  words = ["word","good","best","word"]
Output: []

思路是滑动窗口(sliding window),但是没法套用之前的模板。注意这个题给的条件,words里面每个单词是等长的,这个条件会使得这个题目简单些。首先创建一个hashmap把words里面的所有单词和出现次数都记录下来。接着开始遍历字符串s,每移动一个字符,就要复制一次之前的hashmap,因为这里的思路是需要看从起点i开始的substring是否包含hashmap里面存的所有单词(及其次数)。当找到一个子串的时候,需要判断这个子串是否还在hashmap里,如果这个子串不存在或者次数已经为0了则break,说明以当前i为起点的子串无效;如果这个子串存在于hashmap则--,同时words的个数K也要--,这样当K == 0的时候就可以知道所有单词都遍历完了,可以把这个子串的起始位置i加入结果集了。

时间O(n^2)

空间O(n)

Java实现

 1 class Solution {
 2     public List<Integer> findSubstring(String s, String[] words) {
 3         // corner case
 4         if (s == null || words == null || words.length == 0) {
 5             return new ArrayList<>();
 6         }
 7 
 8         // normal case
 9         List<Integer> res = new ArrayList<>();
10         int n = words.length;
11         int m = words[0].length();
12         HashMap<String, Integer> map = new HashMap<>();
13         for (String str : words) {
14             map.put(str, map.getOrDefault(str, 0) + 1);
15         }
16 
17         for (int i = 0; i <= s.length() - n * m; i++) {
18             HashMap<String, Integer> copy = new HashMap<>(map);
19             int k = n;
20             int j = i;
21             while (k > 0) {
22                 String str = s.substring(j, j + m);
23                 if (!copy.containsKey(str) || copy.get(str) < 1) {
24                     break;
25                 }
26                 copy.put(str, copy.get(str) - 1);
27                 k--;
28                 j += m;
29             }
30             if (k == 0) {
31                 res.add(i);
32             }
33         }
34         return res;
35     }
36 }

 

javascript实现

 1 /**
 2  * @param {string} s
 3  * @param {string[]} words
 4  * @return {number[]}
 5  */
 6 var findSubstring = function (s, words) {
 7     // corner case
 8     if (s == null || words == null || words.length == 0) {
 9         return [];
10     }
11 
12     // normal case
13     let res = [];
14     let n = words.length;
15     let m = words[0].length;
16     let map = {};
17     for (let str of words) {
18         map[str] = (map[str] || 0) + 1;
19     }
20 
21     for (let i = 0; i <= s.length - n * m; i++) {
22         let copy = { ...map };
23         let k = n;
24         let j = i;
25         while (k > 0) {
26             let str = s.substring(j, j + m);
27             if (!copy[str] || copy[str] < 1) {
28                 break;
29             }
30             copy[str]--;
31             k--;
32             j += m;
33         }
34         if (k == 0) {
35             res.push(i);
36         }
37     }
38     return res;
39 };

 

以上是关于[LeetCode] 30. Substring with Concatenation of All Words的主要内容,如果未能解决你的问题,请参考以下文章

leetcode 30 Substring with Concatenation of All Words

19.1.30 [LeetCode 30] Substring with Concatenation of All Words

LeetCode(30) Substring with Concatenation of All Words

LeetCode30. Substring with Concatenation of All Words

leetcode 30. Substring with Concatenation of All Words

LeetCode HashTable 30 Substring with Concatenation of All Words