中文小说网站建设与维护,查找企业信息的网站,河北seo优化_网络建设营销_网站推广服务 - 河北邢台seo,办公室现代简约装修串联所有单词的子串
1 题目描述
https://leetcode.cn/problems/substring-with-concatenation-of-all-words/
给定一个字符串 s 和一个字符串数组 words。 words 中所有字符串 长度相同。
s 中的 串联子串 是指一个包含 words 中所有字符串以任意顺序排列连接起来的子串。 …串联所有单词的子串
1 题目描述
https://leetcode.cn/problems/substring-with-concatenation-of-all-words/
给定一个字符串 s 和一个字符串数组 words。 words 中所有字符串 长度相同。
s 中的 串联子串 是指一个包含 words 中所有字符串以任意顺序排列连接起来的子串。
例如如果 words [“ab”,“cd”,“ef”] 那么 “abcdef” “abefcd”“cdabef” “cdefab”“efabcd” 和 “efcdab” 都是串联子串。 “acdbef” 不是串联子串因为他不是任何 words 排列的连接。 返回所有串联子串在 s 中的开始索引。你可以以 任意顺序 返回答案。
示例 1
输入s “barfoothefoobarman”, words [“foo”,“bar”] 输出[0,9] 解释因为 words.length 2 同时 words[i].length 3连接的子字符串的长度必须为 6。 子串 “barfoo” 开始位置是 0。它是 words 中以 [“bar”,“foo”] 顺序排列的连接。 子串 “foobar” 开始位置是 9。它是 words 中以 [“foo”,“bar”] 顺序排列的连接。 输出顺序无关紧要。返回 [9,0] 也是可以的。
示例 2
输入s “wordgoodgoodgoodbestword”, words [“word”,“good”,“best”,“word”] 输出[] 解释因为 words.length 4 并且 words[i].length 4所以串联子串的长度必须为 16。 s 中没有子串长度为 16 并且等于 words 的任何顺序排列的连接。 所以我们返回一个空数组。
示例 3
输入s “barfoofoobarthefoobarman”, words [“bar”,“foo”,“the”] 输出[6,9,12] 解释因为 words.length 3 并且 words[i].length 3所以串联子串的长度必须为 9。 子串 “foobarthe” 开始位置是 6。它是 words 中以 [“foo”,“bar”,“the”] 顺序排列的连接。 子串 “barthefoo” 开始位置是 9。它是 words 中以 [“bar”,“the”,“foo”] 顺序排列的连接。 子串 “thefoobar” 开始位置是 12。它是 words 中以 [“the”,“foo”,“bar”] 顺序排列的连接。
2 思路
这个题虽然是Hard但是我感觉这也是一个靠暴力做的题没有涉及到太多的技巧。
我的想法是首先统计words中的每个字符串的数量 然后以word.length * word[0].length大小的窗口对s进行遍历统计每个窗口中分割出的元素数量。 如果符合就添加进返回列表中。
3 详细设计
首先我们对words里面的每个字符串进行编码
MapString, Integer maps new HashMap();
int pos 0;
for (String str :words) {if (!maps.containsKey(str)) {maps.put(str, pos);}
}这样我们就可以给予words中每个字符串一个唯一的编号pos记录了一共有多少种word。
接下来我们统计每个word的出现次数
int[] counts new int[pos];
for (String str :words) {counts[maps.get(str)];
}最后我们设置窗口
int end total_len - 1; // 窗口的大小为total_lenword.length * word[0].length()
int start 0;
while (end s.length()) {int[] temp_table new int[pos];for (int i 0; i words.length; i) {// 对窗口内的单词进行分割遍历// s.substring(start i * single_word_len, start (i 1) * single_word_len)// 表示s的第(start1)个窗口中的第(i1)个单词String t s.substring(start i * single_word_len, start (i 1) * single_word_len);if (! maps.containsKey(t)) break; // 如果窗口中出现了不属于words中的字符串跳出此次循环。temp_table[maps.get(t)]; // 统计第(start1)个窗口中的第(i1)个单词的出现次数}boolean flag true;for (int i 0; i pos; i) {if (temp_table[i] ! counts[i]) { // 判断相应单词的出现次数与words中是否一致flag false; // 一旦有一个不一致的设置标志位为falsebreak;}}if (flag) reslist.add(start);start;end;
}整体的时间复杂度应该是接近O(n*2*word.length)
4 代码
class Solution {public ListInteger findSubstring(String s, String[] words) {MapString, Integer maps new HashMap();ListInteger reslist new ArrayList();int total_len words.length * words[0].length();int single_word_len words[0].length();int pos 0;for (String str :words) {if (!maps.containsKey(str)) {maps.put(str, pos);}}int[] counts new int[pos];for (String str :words) {counts[maps.get(str)];}int end total_len - 1;int start 0;while (end s.length()) {int[] temp_table new int[pos];for (int i 0; i words.length; i) {String t s.substring(start i * single_word_len, start (i 1) * single_word_len);if (! maps.containsKey(t)) break;temp_table[maps.get(t)];}boolean flag true;for (int i 0; i pos; i) {if (temp_table[i] ! counts[i]) {flag false;break;}}if (flag) reslist.add(start);start;end;}return reslist;}
}