Substring with Concatenation of All Words 找子串组合的下标 @LeetCode

思路:

把所有的子串存入Hashtable,对原字符串进行O(n2)的搜索,看能不能用完Hashtable所有的字串


本题用了不是很好的暴力法压线通过,下次改成用KMP的方法重写一遍。现在还太弱了,不会KMP。。。T^T

还遇到了很奇怪的问题,在代码中注释体现。


package Level3;

import java.util.ArrayList;
import java.util.Hashtable;

/**
 * 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).
 */
public class S30 {

	public static void main(String[] args) {
		String S = "barfoothefoobarman";
		String[] L = {"foo", "bar"};
//		String S = "a";
//		String[] L = {"a"};
		
		System.out.println(findSubstring(S, L));
	}
	
	// 用暴力法压线通过,未来应该用类似KMP的方法降低复杂度!
	public static ArrayList<Integer> findSubstring(String S, String[] L) {
		
		ArrayList<Integer> ret = new ArrayList<Integer>();
		
        Hashtable<String, Integer> ht = new Hashtable<String, Integer>();
        // 把L中的string全部添加入hashtable
        for (String str : L) {
			if(ht.containsKey(str)){
				ht.put(str, ht.get(str)+1);
			}else{
				ht.put(str, 1);
			}
		}
        
        int wordLen = L[0].length();
        int numberOfWords = L.length;
        
        // Brute force法比较
        for(int i=0; i<=S.length()-numberOfWords*wordLen; i++){
        	// 每次要基于原hashtable新建一个hashtable
        	Hashtable<String, Integer> table = new Hashtable<String, Integer>(ht);
        	int cnt = 0;
        	
        	// j每次都重复地做相同的工作
        	for(int j=i; j<=i+numberOfWords*wordLen-wordLen; j+=wordLen){
        		String substr = S.substring(j, j+wordLen);
            	if(table.containsKey(substr)){
            		// 如果只用这一句会TLE
//            		table.put(substr, table.get(substr)-1);
            		
            		// 改成这样就能压线AC
            		int times = table.get(substr);
                    if(times == 1) table.remove(substr);
                    else table.put(substr, times - 1);
                    
            		cnt++;
            	}else{
            		break;
            	}
        	}
        	
        	if(cnt == numberOfWords){
        		ret.add(i);
        	}
        }
        
        return ret;
    }

}


找到压线通过的方法:http://www.cnblogs.com/lichen782/archive/2013/07/06/leetcode_SubstringwithConcatenationofAllWords.html

KMP的初步认识: http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html

一个基于KMP的解决方法:http://n00tc0d3r.blogspot.com/2013/06/substring-with-concatenation-of-all.html



import java.util.*;

public class Solution {
    public List<Integer> findSubstring(String S, String[] L) {
        List<Integer> ret = new ArrayList<Integer>();
        int m = L.length;
        if(m == 0) {
            return ret;
        }
        int n = L[0].length();
        Hashtable<String, Integer> ht = new Hashtable<String, Integer>();
        for(String word : L) {
            Integer cnt = ht.get(word);
            if(cnt == null) {
                ht.put(word, 1);
            } else {
                ht.put(word, cnt+1);
            }
        }
        
        for(int i=0; i<=S.length()-n*m; i++) {
            Hashtable<String, Integer> tmp = new Hashtable<String, Integer>();
            int j = 0;
            for(j=0; j<m; j++) {
                int k = i + j*n;    // n-characters interval
                String substr = S.substring(k, k+n);
                Integer cntInHt = ht.get(substr);       // check if substr in Hashtable
                Integer cntInTmp = tmp.get(substr);     // check if substr in temporary Ht
                // must be in the original Hashtable and found cnts of character should be less than all available characters
                if(cntInHt != null && (cntInTmp == null || cntInTmp < cntInHt)) {
                    if(cntInTmp == null) {
                        tmp.put(substr, 1);
                    } else {
                        tmp.put(substr, cntInTmp+1);
                    }
                } else {
                    break;
                }
            }
            if(j == m) {        // found all words in L
                ret.add(i);
            }
         }
        
        return ret;
    }
}




你可能感兴趣的:(Substring with Concatenation of All Words 找子串组合的下标 @LeetCode)