zoukankan      html  css  js  c++  java
  • 算法题:串联所有单词的子串

    描述

    给定一个字符串 s 和一些长度相同的单词 words。找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置。

    注意子串要与 words 中的单词完全匹配,中间不能有其他字符,但不需要考虑 words 中单词串联的顺序。

    示例 1:

    输入:
    s = "barfoothefoobarman",
    words = ["foo","bar"]
    输出:[0,9]
    解释:
    从索引 0 和 9 开始的子串分别是 "barfoo" 和 "foobar" 。
    输出的顺序不重要, [9,0] 也是有效答案。
    示例 2:

    输入:
    s = "wordgoodgoodgoodbestword",
    words = ["word","good","best","word"]
    输出:[]

    链接:https://leetcode-cn.com/problems/substring-with-concatenation-of-all-words

    思路

    先用一个hash表存储words的所有单词出现的次数,再依次遍历s,找到与words所有单词总长度相同的窗口,并将这个窗口的每个单词与前面的hash表对比,如果一致就记录下起始点。

    代码

    class Solution {
    public:
        vector<int> findSubstring(string s, vector<string>& words) {
            int w_count = words.size();
            if (w_count == 0) return {};
            int w_size = words[0].size();
            if (w_size == 0) return {};
    
            unordered_map<string, int> hash;
            for (const string& word : words) {
                hash[word]++;
            }
    
            const int size = w_count * w_size;
            int i = 0, j = 0;
            vector<int> res;
            for (;j < s.size();) {
                if (j - i + 1 == size) {
                    unordered_map<string, int> tmp_hash;
                    bool flag = true;
                    for (int k = 0;k < size;k+=w_size) {
                        string sub = s.substr(i+k, w_size);
                        if (hash.find(sub) == hash.end()) {
                            flag = false;
                            break;
                        }
                        tmp_hash[sub]++;
                        if (tmp_hash[sub] > hash[sub]) {
                            flag = false;
                            break;
                        }
                    }
                    if (flag) {
                        res.push_back(i);
                    }
                    i++;
                }
                j++;
            }
    
            return res;
        }
    };
    

    复杂度
    时间复杂度:O(n*m),n是s长度,m是words总长度
    空间复杂度:O(m)

  • 相关阅读:
    java常见面试题汇总(一)
    我的自学之路:java学习路线图分享
    bzoj3714 [PA2014]Kuglarz
    cf478D Red-Green Towers
    cf478C Table Decorations
    cf478B Random Teams
    cf479A Expression
    cf479C Exams
    cf479D Long Jumps
    cf479E Riding in a Lift
  • 原文地址:https://www.cnblogs.com/dinjufen/p/14438659.html
Copyright © 2011-2022 走看看