LeetCode | Substring with Concatenation of All Words

题目

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

For example, given:
S"barfoothefoobarman"
L["foo", "bar"]

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

分析

这道题和Minimum Window Substring思路一致,也是双指针遍历。

需要注意的时,移动指针时,按单词长度移动。

代码

import java.util.ArrayList;
import java.util.HashMap;

public class SubstringWithConcatenationOfAllWords {
	public ArrayList<Integer> findSubstring(String S, String[] L) {
		ArrayList<Integer> results = new ArrayList<Integer>();
		if (S == null || S.length() == 0 || L == null || L.length == 0) {
			return results;
		}
		int N = S.length();
		int M = L.length;
		int T = L[0].length();

		HashMap<String, Integer> needToFind = new HashMap<String, Integer>();
		HashMap<String, Integer> hasFound = new HashMap<String, Integer>();
		for (int i = 0; i < M; ++i) {
			int count = 1;
			if (needToFind.containsKey(L[i])) {
				count += needToFind.get(L[i]);
			}
			needToFind.put(L[i], count);
		}

		for (int j = 0; j < T; ++j) {
			int hits = 0;
			int start = j;
			for (int i = j; i + T <= N; i += T) {
				String word = S.substring(i, i + T);
				if (!needToFind.containsKey(word)) {
					hasFound.clear();
					hits = 0;
					start = i + T;
					continue;
				}
				int count = 1;
				if (hasFound.containsKey(word)) {
					count += hasFound.get(word);
				}
				if (count <= needToFind.get(word)) {
					++hits;
					hasFound.put(word, count);
				} else {
					String startWord = S.substring(start, start + T);
					while (!startWord.equals(word)) {
						int value = hasFound.get(startWord) - 1;
						hasFound.put(startWord, value);
						--hits;
						start += T;
						startWord = S.substring(start, start + T);
					}
					start += T;
				}
				if (hits == M) {
					results.add(start);
					String startWord = S.substring(start, start + T);
					int value = hasFound.get(startWord) - 1;
					hasFound.put(startWord, value);
					--hits;
					start += T;
				}
			}
			hasFound.clear();
		}
		return results;
	}
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值