30. 모든 단어가 연결된 하위 문자열

설명



문자열s과 동일한 길이의 문자열 배열words이 제공됩니다. s에 있는 하위 문자열의 모든 시작 인덱스를 반환합니다. 즉, words에 있는 각 단어를 순서에 관계없이 정확히 한 번 연결하고 중간 문자 없이 반환합니다.

답변은 어떤 순서로든 반환할 수 있습니다.

예 1:




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


예 2:




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


예 3:




Input: s = "barfoofoobarthefoobarman", words = ["bar","foo","the"]
Output: [6,9,12]


제약:


  • 1 <= s.length <= 104
  • s 영문 소문자로 구성됩니다.
  • 1 <= words.length <= 5000
  • 1 <= words[i].length <= 30
  • words[i] 영문 소문자로 구성됩니다.



  • 解题



    方法一



    思路



    两个滑动窗口

    代码




    public List<Integer> findSubstring(String s, String[] words) {
        ArrayList<Integer> res = new ArrayList<>();
        HashMap<String, Integer> map = new HashMap<>();
        int one_word = words[0].length();
        int word_num = words.length;
        int all_len = one_word * word_num;
        for (String word : words) {
            map.put(word, map.getOrDefault(word, 0) + 1);
        }
    
        for (int i = 0; i < s.length() - all_len + 1; i++) {
            HashMap<String, Integer> tmp_map = new HashMap<>();
            for (int j = 0; j < all_len; j += one_word) {
                String w = s.substring(i + j, i + j + one_word);
                if (!map.containsKey(w)) {
                    break;
                }
                tmp_map.put(w, tmp_map.getOrDefault(w, 0) + 1);
            }
            if (map.equals(tmp_map))
                res.add(i);
        }
        return res;
    }
    


    复杂度分析


  • 时间复杂度: O(nm)
  • 空间复杂度:O(m)



  • 방법



    思路



    代码




    class Solution {
    public:
        vector<int> findSubstring(string s, vector<string>& words) {
            vector<int> res;
            if (words.empty()) return res;
            int m = words.size(), w = words[0].size(), mw = m * w, cnt = 0;
            unordered_map<string, int> wf, wd;
            for (auto& word : words) wf[word]++;
            for (int i = 0; i < w; i++) {
                for (int j = i; j + w <= s.size(); j += w) {
                    if (j >= i + mw) {
                        string word = s.substr(j - mw, w);
                        wd[word]--;
                        if (wd[word] < wf[word]) cnt--;
                    }
                    string word = s.substr(j, w);
                    wd[word]++;
                    if (wd[word] <= wf[word]) cnt++;
                    if (cnt == m) res.push_back(j - (m - 1) * w);
                }
                wd.clear();
                cnt = 0;
            }
    
            return res;
        }
    };
    


    复杂度分析


  • 时间复杂度: O(n*w)
  • 空间复杂度:O(n)
  • 좋은 웹페이지 즐겨찾기