【leetcode】String——Substring with Concatenation of All Words(30)

题目:

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].

经典的two pointers && sliding window 题目

思路1:自己的思路

用HashMap<String,Integer>map 存words的信息(不用set是因为word可能会存在重复)。

内部循环的方式经过多次考虑,采用两层循环,最外层循环的是word的长度(因为题目说了word长度一致),内层使用two pointers,根据word长度截取String

这个有点儿像希尔排序里面的思维。

在内层循环中,使用curMap记录window内部的信息。这里,curMap初始化和map一样,如果截取的word匹配,则对应位置减一,如果为零,则remove;

这样判断是否完全匹配只要判断curMap是否为空。

然后一开始end指针后移,扩大window的范围,一旦,subString不是words[]里面的,则跳出循环,重置变量;

如果出现了subString在map中,但是不在curMap中,说明,subString是合法的,但是出现的次数多了一个;这时候开始移动start指针,直到把相同的subString从window左侧“吐出”(在移动start过程中,要不断修改curMap),再继续移动end;

如果过程中出现了curMap为空,添加start到结果集;然后移动start,window吐出一个元素,再继续。

代码1:

public List<Integer> findSubstring(String s, String[] words) {
	List<Integer> res = new ArrayList<>();
	int len = words[0].length();
	Map<String,Integer>map = new HashMap<String,Integer>();

	for(String word:words){
		map.put(word, map.containsKey(word)?map.get(word)+1:1);
	}
	int start,end;
	for(int index = 0; index<len; index++){
		for(start = index;start<s.length()-words.length*len+1;start+=len){
			Map<String,Integer>curMap = new HashMap<String,Integer>(map);
			end = start+len;
			while(end<=s.length()){
				String sub = s.substring(end-len, end);
				if(curMap.containsKey(sub)){
					if(curMap.get(sub)==1){
						curMap.remove(sub);
						if(curMap.isEmpty()){
							res.add(start);
							curMap.put(s.substring(start,start+len), 1);
							start+=len;
						}
					}else{
						curMap.put(sub, curMap.get(sub)-1);
					}
				}else if(map.containsKey(sub)){
					while(start<end){
						String temp = s.substring(start, start+len);
						if(!temp.equals(sub)){
							curMap.put(temp, curMap.containsKey(temp)?curMap.get(temp)+1:1);
							start+=len;
						}else{
							start+=len;
							break;
						}
					}
				}else 
					break;//subString 不匹配
				end+=len;
			}
		}
	}

	return res;
}

思路2:借鉴了大神的思路了

总体的思路其实和上面差不多,只不过大神们用了一个标记变量count,来表示是否完全匹配。

不多说了,贴链接~~

https://leetcode.com/discuss/20151/an-o-n-solution-with-detailed-explanation

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值