标签:art res 一个 amp let foo cat 字符 too
串联所有单词的子串。题意是给定一个字符串 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
标签:art res 一个 amp let foo cat 字符 too
原文地址:https://www.cnblogs.com/aaronliu1991/p/12630245.html