[LeetCode30]Substring with Concatenation of All Words

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

Analysis:

Try to think this problem straightforward:
Say in L there are m strings with length n. 
What string is required to match in S?     A length of m*n string start with each position in S.
What is a match?  In the m*n long string, every string in L appear only once.

So the algorithm is:
Scan every m*n long string start from each position in S, see if all the strings in L have been appeared only once using Map data structure. If so, store the starting position.

Yes, do not consider any DP or DFS solutions, just using the hash map and loop.

注意考虑L中可能含有重复字符串,需要用两个map

c++实现

vector<int> findSubstring(string S, vector<string> &L) {
        map<string, int> expectCount;
    map<string, int> realCount;
    vector<int> result;
    int row = L.size();
    if(row == 0) return result;
    int len = (int)L[0].size();
    for(int i=0; i< L.size(); i++){
        expectCount[L.at(i)]++;
    }
    for(int i=0; i<=(int)S.size()- row*len;i++){
        realCount.clear();
        int j=0;
        for(; j<row; j++){
            string str = S.substr(i+j*len,len);
            if(expectCount.find(str) != expectCount.end()){
                realCount[str]++;
            }else{
                break;
            }
            if(realCount[str]>expectCount[str])
                break;
        }
        if(j == row)
            result.push_back(i);
    }
    return result;
    }


Java实现

public ArrayList<Integer> findSubstring(String S, String[] L) {
        ArrayList<Integer> result = new ArrayList<Integer>();
        int num = L.length;
        int eachLen = L[0].length();
        if(num == 0 || eachLen ==0) return result;
        HashMap<String, Integer> hMap2 = new HashMap<String,Integer>();
    	for(int j=0;j<num;j++){
        	int val = 1;
			if(hMap2.containsKey(L[j])){
        		val = hMap2.get(L[j]);
        		val++;
			}
    		hMap2.put(L[j], val);
    	}
        for(int i=0;i<=S.length()-num*eachLen;i++){
        	HashMap<String, Integer> hMap = new HashMap<String,Integer>();
        	for(int j=0;j<num;j++){
        		hMap.put(L[j], 0);
        	}
        	int k =0 ;
        	while(k<num){
        		String str = S.substring(i+k*eachLen, i+eachLen*(k+1));
        		if(hMap.containsKey(str)){
        			int val = hMap.get(str);
        			hMap.put(str, ++val);
        			if(hMap.get(str)>hMap2.get(str)) break;
        			
        		}else{
        			break;
        		}
        		k++;
        	}
        	if(k == num) result.add(i);
        }
        
        return result;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值