LeetCode0030-串联所有单词的子串
题目:
给定一个字符串 s 和一些长度相同的单词 words。找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置。
注意子串要与 words 中的单词完全匹配,中间不能有其他字符,但不需要考虑 words 中单词串联的顺序。
示例 1:
输入:
s = "barfoothefoobarman",
words = ["foo","bar"]
输出:[0,9]
解释:
从索引 0 和 9 开始的子串分别是 "barfoo" 和 "foobar" 。
输出的顺序不重要, [9,0] 也是有效答案。
示例 2:
输入:
s = "wordgoodgoodgoodbestword",
words = ["word","good","best","word"]
输出:[]
分析:
首先,直接的思路,判断每个子串是否符合,符合就把下标存起来,最后返回即可。
如上图,利用循环遍历i,依次后移,判断每个子串是否符合即可。
怎么判断子串是否符合?是该问题的难点,由于子串包含的单词顺序并不需要固定,如果俩个单词A,B,只需要判断子串是否是AB或BA。如果是三个单词A,B,C也还行,但是如果单词过多,那么就奔溃了。
用俩个HashMap来解决,首先,把所有的单词存到HashMap里,kye直接存单词,value存单词出现的个数(因为给出的单词可能会重复)。然后扫描子串的单词,如果当前扫描的单词在之前的HashMap中,并判断新的HashMap中该单词的value是不是大于之前的HashMap该单词的value,如果大了,就标示该子串不是我们要找的,接着判断下一个子串就可以了。如果不大于,那我们接着判断下一个单词的情况。子串扫描结束,如果子串的全部单词都符合,那么该子串就解中的一个。例如:
把words存放到HashMap 中
然后遍历子串的每个单词。
第一个单词在HashMap1中,然后我们把foo存到HashMap2中,并且比较此时的foo的value和HashMap1中的foo的 value,1<2,继续扫描。
第二个单词也在 HashMap1 中,然后把 foo 存到 HashMap2 中,因为之前已经存过了,所以更新它的 value 为 2 ,然后继续比较此时 foo 的 value 和 HashMap1 中 foo 的 value,2 <= 2,所以继续扫描下一个单词。
第三个单词也在 HashMap1 中,然后把 foo 存到 HashMap2 中,因为之前已经存过了,所以更新它的 value 为 3,然后继续比较此时 foo 的 value 和 HashMap1 中 foo 的 value,3 > 2,所以表明该字符串不符合。然后判断下个子串就好了。
当然上边的情况都是单词在 HashMap1 中,如果不在的话就更好说了,不在就表明当前子串肯定不符合了,直接判断下个子串就好了。
代码:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List