Algorithm之路三十:Substring with Concatenation of All Words

题目:

给出一个字符串S,和一个字符串数组words,words中包括很多个字符串,每个字符串的长度都相同,并且可能相同的字符串出现多次,现在要求由words中所有的字符串连接之后形成的字符串在S出现的位置。

举例:

S: "barfoothefoobarman"
words: ["foo", "bar"]
返回的结果应该是[0,9],因为barfoo和foobar在S中出现处的头部索引是0和9

思路:

在S中寻找的字符串Str由words中所有的字符串组成,那么字符串Str的长度则由words决定,并且Str按照words中的字符串的长度分割之后,和words中的字符串是一一对应的。例如例子中的barfoo的长度为6,并且将barfoo按照三个三个字母分割后得到bar和foo,在words中的字符串一一对应。

那么从上面的想法中可以得到这样一个方法:

首先,统计words中出现的字符串,和每个字符串出现的个数。

然后,在S中找到一个长度为words字符串个数N*字符串长度L的子串Str,将Str分割成N个长度为L的小串,统计这些串的种类和个数,或者判断这些串是否在words中出现,出现的次数是否相同,如果不同,则继续往下判断下一个长度为N*L的S的子串。

代码:

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

public class Substring_with_Concatenation_of_All_Words {

	public static List<Integer> findSubstring(String s, String[] words)
	{
		List<Integer> result = new ArrayList<>();
		int words_size = words.length,s_length = s.length();
		if(words_size <= 0 || s_length <= 0) return result;
		int length_each_word = words[0].length();
		HashMap<String,Integer> map = new HashMap<>();
		HashMap<String,Integer> map2 = map;
		for(String s1 : words)map.put(s1, map.containsKey(s1)?map.get(s1)+1:1);
		for(int i = 0;i < s_length - words_size * length_each_word + 1;i++)
		{
			map2 = (HashMap<String, Integer>) map.clone();
			String str = s.substring(i, i + words_size * length_each_word);
			int j,k = 0;
			for(j = 0;j < str.length();j = j + length_each_word)
			{
				String str2 = str.substring(j,j + length_each_word);
				if(map2.containsKey(str2))//barfoofoobarthefoobarman
				{
					int times = map2.get(str2);
					if(times > 0) map2.put(str2, --times);
					else{k = 1; break;}
				}
				else{k = 1; break;}
			}
			if(k == 0)
				result.add(i);
			k = 0;
			map2.clear();
		}
		return result;
    }
	public static void main(String[] args)
	{
		String s = "barfoofoobarthefoobarman";
		String[] words = {"bar","foo","the"};
		System.out.println(findSubstring(s, words));
	}

}


时间复杂度:

设LS为字符串S的长度,N为words中字符串的个数,L为words中字符串的长度。

最坏情况下,判断的S子串的个数为LS-N*L,每个子串都要经过N次的在hashmap中查找。这种情况下,时间复杂度为O(N*(LS-N*L))。

空间复杂度:

由N和解的个数决定。hashmap占用的空间O(N)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值