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 all starting indices of substring(s) in s that is a concatenation of each word in words exactly 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).

解题思路:

首先设置一个HashMap,里面键值为单词,元素值为对应单词出现的次数,将其作为比较的模板。

我们首先在一个大的循环里面获得字符串的第一个位置开始的第一个单词,查看上述的模板Map中是否存在这个单词。如果不存在,那么外面的大循环直接后移一位,匹配下一个位置开始的单词。同时内嵌循环,用于逐个单词进行排查。如果查找是存在的,那么我们把这个单词加入到新的Map中,同时统计次数也需要递增。接下来查看这个新Map中的该单词出现的次数是否小于的个等于模板中该单词出现的次数,如果大于该次数,说明情况是不符合要求的,跳出该内层循环,外层循环的指针后移。

最后如果内层循环如果顺利走完,则说明从该位置开始所有的单词都是匹配的,那么将该位置添加到List中,否则外层循环指针指向下一个字符的外置,继续开始类似的判断。

代码如下:

public class Solution {
    public List<Integer> findSubstring(String s, String[] words) {
		List<Integer> list = new ArrayList<Integer>();
		Map<String, Integer> map = new HashMap<String, Integer>();
		Map<String, Integer> tmp = new HashMap<String, Integer>();
		int sLength = s.length();
		int wordsNum = words.length;
		int wordsLength = words[0].length();
		int j;

		if (sLength < wordsNum || wordsNum == 0)
			return list;
		for (int i = 0; i < wordsNum; i++) {
			if (map.containsKey(words[i]))
				map.put(words[i], map.get(words[i]) + 1);
			else
				map.put(words[i], 1);
		}
		for (int i = 0; i <= sLength - wordsNum * wordsLength; i++) {
			tmp.clear();
			for (j = 0; j < wordsNum; j++) {
				String word = s.substring(i + j * wordsLength, i + j
						* wordsLength + wordsLength);
				if (!map.containsKey(word))
					break;
				if (tmp.containsKey(word))
					tmp.put(word, tmp.get(word) + 1);
				else
					tmp.put(word, 1);
				if (tmp.get(word) > map.get(word))
					break;
			}
			if (j == wordsNum)
				list.add(i);
		}
		return list;
	}
}
原文地址:https://www.cnblogs.com/zihaowang/p/4507979.html