[算法分析与设计] leetcode 每周一题: 030. Substring with Concatenation of All Words


题目链接: 

30. Substring with Concatenation of All Words




题目大意:
给定字符串 s 和单词列表 words (其中所有 word 为等长字符串, 可以重复), 找出字符串 s 的 所有满足条件的子串的首字符的索引(index) ; 其中, 所有子串的内容均为 words 中所有 word 首尾连结而成的(顺序随意), 且所有单词均出现且仅完整出现一次 ;


例如: 给定 s: "barfoothefoobarman", words: ["foo", "bar"], 则输出可以是: [0, 9]




解题过程:

(1) 考虑所有单词(word) 等长且必须在目标子串中互相首尾相连(故而 目标子串长度恒定), 故可以在遍历字符串 s 时不断进行逐词的检查(分别从每个下标), 一旦发现不符合要求立即转而开始从下一个字符开始进行检查 ;

(2) 一开始没有想到 words 中允许重复, 所以直接用 unordered_set 作处理, 后来发现重复的存在后就改用 unordered_multiset, 但这样便导致了超时, 所以还是要老老实实用 unordered_map (直接记录每个词的重复个数) ;


(*) 其实, 既然已经确定 "所有单词(word) 等长且必须在目标子串中互相首尾相连", 那么应该可以直接对 输入字符串 s 做逐词的检查, 也即 以词长为步进, (我这里就只是先逐个索引地遍历再(针对)每一次作处理, 显然有很多冗余检查), 因为目标子串所在的 "轨迹" 在 s 中是固定且有限的 ;




代码如下:

class Solution {
public:
    vector<int> findSubstring(string s, vector<string>& words) {
        vector<int> ret;

        auto wordLength = words.front().size();
        if (s.size() < wordLength*words.size()) { return ret; }

        unordered_map<string, int> existedWords;
        for (auto w : words) {
            existedWords[w]++;
        }

        for (size_t i = 0; i <= s.size() - wordLength; i++) {
            bool match = true;
            unordered_map<string, int> matchedWords;
            for (auto j = i; j < i + wordLength * words.size(); j += wordLength) {
                auto word = s.substr(j, wordLength);
                if (existedWords[word] < 1 || 
                    matchedWords[word] >= existedWords[word]) {
                    match = false;
                    break;
                }
                matchedWords[word]++;
            }
            if (match) {
                ret.push_back(i);
            }
        }

        return ret;
    }
};




Runtime: 256 ms


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值