030 Substring with Concatenation of All Words

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 words exactly once and without any intervening characters.

Example:

Input:
s = "barfoothefoobarman",
words = ["foo","bar"]
Output: [0,9]
Explanation: Substrings starting at index 0 and 9 are "barfoor" and "foobar" respectively.
The output order does not matter, returning [9,0] is fine too.

Input:
s = "wordgoodgoodgoodbestword",
words = ["word","good","best","word"]
Output: []

解釋下題目:

這題目我看了半天才看懂!就是給定一個字符串s,還有若干個單詞的數(shù)組,每個單詞都是相同的長度,然后它們有個全排列,找出這個全排列中的任何一種可能在字符串s中出現(xiàn)的位置。就是如果我的單詞數(shù)組是["a","b","c"],那么如果s中有abc,acb,bca,bac,cab,cba這六種可能中的任何一種符合,都要輸出。(PS:肯定不能全排列的)

1. 利用hashmap

實際耗時:225ms

public List<Integer> findSubstring(String s, String[] words) {
        List<Integer> res = new ArrayList<>();

        //有多少單詞
        int numOfWord = words.length;

        if (numOfWord == 0) {
            return res;
        }

        //每個單詞的長度 #題中說了每個單詞長度一樣
        int wordLen = words[0].length();

        //把所有單詞放進map1里面
        Map<String, Integer> map1 = stringToMap(words, numOfWord);

        for (int i = 0; i < s.length() - wordLen * numOfWord + 1; i++) {
            Map<String, Integer> map2 = getMap(i, wordLen, numOfWord, s);
            if (compareMap(map1, map2)) {
                res.add(i);
            }
        }
        return res;
    }

    //用所給的字符串,指定開始,并且指定每個單詞的長度,來構(gòu)造map
    private Map<String, Integer> getMap(int start, int wordLen, int numOfWord, String s) {
        String words[] = new String[numOfWord];
        int j = 0;
        for (int i = start; i < start + numOfWord * wordLen; i = i + wordLen) {
            words[j] = s.substring(i, i + wordLen);
            j++;
        }
        return stringToMap(words, numOfWord);
    }

    private Map<String, Integer> stringToMap(String words[], int numOfWord) {
        Map<String, Integer> map = new HashMap<>();
        for (int i = 0; i < numOfWord; i++) {
            if (map.containsKey(words[i])) {
                int count = map.get(words[i]);
                count++;
                map.put(words[i], count);
            } else {
                map.put(words[i], 1);
            }
        }
        return map;
    }

    private boolean compareMap(Map<String, Integer> m1, Map<String, Integer> m2) {

        Iterator<Map.Entry<String, Integer>> iter1 = m1.entrySet().iterator();
        while (iter1.hasNext()) {
            Map.Entry<String, Integer> entry1 = iter1.next();
            int m1value = entry1.getValue() == null ? -1 : entry1.getValue();
            int m2value = m2.get(entry1.getKey()) == null ? -2 : m2.get(entry1.getKey());
            if (m1value != m2value) {
                return false;
            }
        }
        return true;
    }

??思路是這樣的,全排列是絕對不可取的!那就用hashmap來存唄,上面的abc就可以存成{'a':1,'b':1,'c':1},然后去比較兩個hashmap是否相同。這篇文章寫得更詳細,而且還有優(yōu)化。

時間復(fù)雜度O(n*m) n是s的長度,m是單詞個數(shù)
空間復(fù)雜度O(2*m) m是單詞個數(shù)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容