You are given a string, s, and a list of words, words, that are all of the same length. Find all starting indices of substring(s) in s that is a concatenation of each word in wordsexactly once and without any intervening characters.

For example, given:
s: "barfoothefoobarman"
words: ["foo", "bar"]

You should return the indices: [0,9].
(order does not matter).

问题:给定一个字符串 s 和 一列单词 words 。找出 s 中所有满足下面条件的全部子字符串的开始下标:要求子字符串恰好由 words 的所有单词拼接而成,每个单词仅对应地出现一次。

由于 words 里面单词是无序的,目标子字符串的成员单词也是无序的,所以,考虑用 Hashtable 作为数据存储。

需要充分利用的两个题目条件:

1. 所有单词等长

2. 目标子字符串是由单词连续无中断地连接而成

根据上面两个条件,可以将 s 全部分割为长度为 length 的子字符串,共有 length 种分法。length 种分法会覆盖全部需要找的子字符串。

对于每一种分割,可以将长度为 length 的子字符串视为不再分割的单元,利用滑动窗口算法(Slide Window Algorithm),线性时间找到符合条件的目标子字符串,O(n/length) 复杂度,其中 n 为 s 的长度。一共有 length 种分发,则耗时 O(length * n/length) = O(n)。

算法实现思路

将 s 全部分割为长度为 length 的连续子串的方法,一共有 length 种。

对于每一种 k (0 <= k < length, 表示开始分割的起始下标 ) 有:

  以 k 为起始位置,长度为 length 子字符串即为一个待验证子串 subs

  左右指针指向首个 subs

  若右指针指向的 subs 是要找的 word, 并且已记录的次数小于需要找到的次数,则记录新找到一个 subs,右指针右移

  若右指针指向的 subs 是要找的 word,并且已记录的次数等于需要找到的次数, 则将左指针当前单词从记录中排除,并左指针右移,重复此操作直到从记录中排除一个右指针当前的 subs。使得 [ subs 已记录的次数小于需要找到的次数 ]。

  若右指针指向的 subs 不是要找的 word,则右指针右移,左指针指向右指针位置,并情况记录。

  若已找到的记录(左右指针内元素)恰好等于需要找到全部 words ,则保存左指针所在位置,即为一个需要找的下标。然后,将左指针当前元素从记录中排除,左指针右移。

实现代码

import java.util.Hashtable;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set; class Utility{ /**
* reset the value of matched result str_cnt_mch
*
* @param str_cnt_mch
*/
public static void resetHashtable(Hashtable<String, Integer> str_cnt_mch){
Set<Entry<String, Integer>> set = str_cnt_mch.entrySet();
for (Entry<String, Integer> s_c : set){
s_c.setValue(0);
}
}
} public class Solution {
public List<Integer> findSubstring(String s, String[] words) {
List<Integer> res = new LinkedList<Integer>(); Hashtable<String, Integer> str_cnt = new Hashtable<String, Integer>();
Hashtable<String, Integer> str_cnt_mch = new Hashtable<String, Integer>(); for (String wrd : words) {
if (str_cnt.containsKey(wrd)) {
str_cnt.put(wrd, str_cnt.get(wrd) + 1);
} else {
str_cnt.put(wrd, 1);
} str_cnt_mch.put(wrd, 0);
} int length = words[0].length(); for (int k = 0; k < length; k++) { int lft = k;
int rgh = k; Utility.resetHashtable(str_cnt_mch);
int mchCnt = 0; while (rgh + length <= s.length()) { String subs = s.substring(rgh, rgh + length); if (str_cnt.containsKey(subs)) { if (str_cnt_mch.get(subs) < str_cnt.get(subs)) { str_cnt_mch.put(subs, str_cnt_mch.get(subs) + 1);
mchCnt++; rgh += length; } else {
// the number of subs in str_cnt_mch is the same as that
// in str_cnt while (true) { String subsl = s.substring(lft, lft + length); str_cnt_mch.put(subsl, str_cnt_mch.get(subsl) - 1);
mchCnt--; lft +=length; if (subsl.equals(subs)) {
break;
}
}
}
} else {
// subs is not a word in words
Utility.resetHashtable(str_cnt_mch);
mchCnt = 0; rgh = rgh + length;
lft = rgh;
} if (mchCnt == words.length){
res.add(lft); String subsl = s.substring(lft, lft + length);
str_cnt_mch.put(subsl, str_cnt_mch.get(subsl) - 1);
mchCnt--; lft = lft + length;
}
}
} return res;
}
}

参考资料:

Substring with Concatenation of All Words -- LeetCode, Code_Ganker, CSDN

[LeetCode] 30. Substring with Concatenation of All Words 解题思路 - Java的更多相关文章

  1. LeetCode - 30. Substring with Concatenation of All Words

    30. Substring with Concatenation of All Words Problem's Link --------------------------------------- ...

  2. leetCode 30.Substring with Concatenation of All Words (words中全部子串相连) 解题思路和方法

    Substring with Concatenation of All Words You are given a string, s, and a list of words, words, tha ...

  3. Java [leetcode 30]Substring with Concatenation of All Words

    题目描述: You are given a string, s, and a list of words, words, that are all of the same length. Find a ...

  4. [LeetCode] 30. Substring with Concatenation of All Words 串联所有单词的子串

    You are given a string, s, and a list of words, words, that are all of the same length. Find all sta ...

  5. [leetcode]30. Substring with Concatenation of All Words由所有单词连成的子串

    You are given a string, s, and a list of words, words, that are all of the same length. Find all sta ...

  6. LeetCode 30 Substring with Concatenation of All Words(确定包含所有子串的起始下标)

    题目链接: https://leetcode.com/problems/substring-with-concatenation-of-all-words/?tab=Description   在字符 ...

  7. [LeetCode] 30. Substring with Concatenation of All Words ☆☆☆

    You are given a string, s, and a list of words, words, that are all of the same length. Find all sta ...

  8. [Leetcode][Python]30: Substring with Concatenation of All Words

    # -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 30: Substring with Concatenation of All ...

  9. LeetCode HashTable 30 Substring with Concatenation of All Words

    You are given a string, s, and a list of words, words, that are all of the same length. Find all sta ...

随机推荐

  1. 使用<input>标签做了两个按钮, 按钮之间间距如何去掉

    遇到的问题: 使用<input>标签做了两个按钮, 按钮之间有个间距不知道怎么去掉. 如下图: 问题解决: <input>是内联块状元素(inline-block); 内联元素 ...

  2. HDU5317

    题意:定义一个数K,最小质因数形式为K = a*b*c形式(如12 = 2*2*3),相同只取一个(所以12只能取2,3两个,既F[12]=2)给L,R区间,找出区间内最大的F[x](L<=x& ...

  3. Google与微软为jQuery等类库提供的CDN服务

    相关链接: Google:  http://code.google.com/apis/ajaxlibs/Microsoft:  http://www.asp.net/ajaxlibrary/cdn.a ...

  4. 本地代码上传 -> Github

    首先在控制台cd到你的本地项目,这里以teat为例 1.执行命令:  git init 2.将项目文件添加到仓库中:  git add . (可以是指定文件,将“.”转换为指定文件) 3.接下来com ...

  5. Char Varchar Nvarchar区别

    char和varchar是一样的字符型,不同在于,varchar比char更灵活,精确,且不占内存空间,当你取同样的字符时,char会在该字符后面加上空格,而varchar则只取得这个字符,比如有字段 ...

  6. 3.题目:求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。例如2+22+222+2222+22222(此时共有5个数相加),几个数相加有键盘控制。

    public static void main(String[] args) {                Scanner scanner=new Scanner(System.in);      ...

  7. 水仙花 AC 杭电

    水仙花数 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  8. Java高精度学习第一弹

    为了快速解决高精度问题,总算是要来接触java了,算上这学期要开java的课了,好好学习吧! 拿来练手的是hdu的1002,高精度加法. import java.util.*; import java ...

  9. 黑马程序员—C语言的函数、数组、字符串

    ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 一.函数 定义:函数是代码复用的一种机制. 函数的基本语法: 返回类型 函数名 ( 参数类型 参 ...

  10. iOS编程修改系统音量

    iOS的AVFoundation框架提供了基本的音视频播放工具,我们基本上可以靠其中提供的类完成绝大部分的音视频播放任务.但是在音频播放的输出音量的处理上,苹果的策略比较保守.尽管AVPlayer和A ...