leetcode-30 Substring with Concatenation of All Words

问题描述:

You are given a string, S, and a list ofwords, L, that are all of the same length. Find all startingindices of substring(s) in S that is a concatenation of each word in L exactlyonce and without any intervening characters.

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

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

 

问题分析:

给定一个字符串S和一个字符串数组L,L中的字符串长度都相等,找出S中所有的子串恰好包含L中所有字符各一次,返回子串的起始位置。

采用窗口法;

将所有待级联的字符串数组L添加到一个HashMap中;

 

代码:

public class Solution {

    public List<Integer> findSubstring(String S, String[] L) {
    	List<Integer> result = new ArrayList<Integer>();

    	if (L.length == 0 || S.length() < L.length * L[0].length())
    		return result;
    	int allNum = L.length, lLength = L[0].length();
    	HashMap<String, Integer> allMap = new HashMap<String, Integer>(), curMap = new HashMap<>();

    	// 将L中所有子字符串添加到allMap中
    	for (String s : L) 
    		allMap.put(s, allMap.containsKey(s) ? allMap.get(s) + 1 : 1);

    	// 窗口法进行匹配
    	for (int start = 0; start < lLength; start++) {
			curMap.clear();
			int count = 0; // 用以统计已经级联的单词个数
			for (int left = start, right = start; right + lLength < S.length(); right += lLength) {
				String str = S.substring(right, right + lLength);

				if (allMap.containsKey(str)) {
					curMap.put(str, curMap.containsKey(str) ? curMap.get(str) + 1 : 1);

					if (curMap.get(str) <= allMap.get(str)) 
						count++;
					while (curMap.get(str) > allMap.get(str)) {
						String temp = S.substring(left, left + lLength);
						curMap.put(temp, curMap.get(temp) - 1);
						if (curMap.get(temp) < allMap.get(temp))
							count--;
						left += lLength;
					}

					if (count == allNum) {
						result.add(left);

						String temp = S.substring(left, left + lLength);
						curMap.put(temp, curMap.get(temp) - 1);
						count --;
						left += lLength;
					}
				} else { // 如果L中没有的单词,则直接跳过该段,窗口移动到下一段
					curMap.clear();
					left = right + lLength;
					count = 0;
				}
			}
    	}
    	return result;
    }
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值