30. 串联所有单词的子串

本文参考https://www.cnblogs.com/ariel-dreamland/p/9134212.html
一开始的思路是使用递归做出words所有结合情况的字典
然后在s中截取words长度去查字典
结果超时了……

超时代码

class Solution {
public:
	void dfs(vector<string>words, int chang, int step, vector<int>book, 
		string dd, unordered_map<string, int>&hash)
	{
		if (step == chang)
		{
			hash[dd] = 1;
			return;
		}
		for (int i = 0; i < chang; i++)
		{
			if (book[i] == 0)
			{
				book[i] = 1;
				dfs(words, chang, step + 1, book, dd + words[i], hash);
				book[i] = 0;
			}
		}
		return;
	}
	vector<int> findSubstring(string s, vector<string>& words) {
        if(words.empty()||s.empty())
            return {};
		vector<int>re;
		unordered_map<string, int>hash;
		int c = s.size(), b = words.size();
		int f = 0;
		for (int i = 0; i < b; i++)
			for (auto v : words[i])
				f++;
		vector<int>book;
		for (int i = 0; i < b; i++)
			book.push_back(0);
		dfs(words, b, 0, book, "", hash);
		for (int i = 0; i <= c - f; i++)
		{
			string st = s.substr(i, f);
			if (hash.find(st) != hash.end())
				re.push_back(i);
		}
		return re;
	}
};

别人家的代码
不必做出所有情况
每次找出给定单词长度的子串,看其是否在第一个哈希表里,如果没有,则break,如果有,则加入第二个哈希表,但相同的词只能出现一次,如果多了,也break

class Solution {
public:
    vector<int> findSubstring(string s, vector<string>& words) {
        vector<int> res;
        if (s.empty() || words.empty()) return res;
        int n = words.size(), m = words[0].size();
        unordered_map<string, int> m1;
        for (auto &a : words) ++m1[a];//这里m1的值的初始值默认为0
        for (int i = 0; i <= (int)s.size() - n * m; ++i) {
            unordered_map<string, int> m2;
            int j = 0; 
            for (j = 0; j < n; ++j) {
                string t = s.substr(i + j * m, m);
                if (m1.find(t) == m1.end()) break;
                ++m2[t];
                if (m2[t] > m1[t]) break;
            }
            if (j == n) res.push_back(i);
        }
        return res;
    }
};

围观大神代码

class Solution {
public:
    vector<int> findSubstring(string s, vector<string>& words) {
        if (s.empty() || words.empty()) return {};
        vector<int> res;
        int n = s.size(), cnt = words.size(), len = words[0].size();
        unordered_map<string, int> m1;
        for (string w : words) ++m1[w];
        for (int i = 0; i < len; ++i) {
            int left = i, count = 0;
            unordered_map<string, int> m2;
            for (int j = i; j <= n - len; j += len) {
                string t = s.substr(j, len);
                if (m1.count(t)) {
                    ++m2[t];
                    if (m2[t] <= m1[t]) {
                        ++count;
                    } else {
                        while (m2[t] > m1[t]) {
                            string t1 = s.substr(left, len);
                            --m2[t1];
                            if (m2[t1] < m1[t1]) --count;
                            left += len;
                        }
                    }
                    if (count == cnt) {
                        res.push_back(left);
                        --m2[s.substr(left, len)];
                        --count;
                        left += len;
                    }
                } else {
                    m2.clear();
                    count = 0;
                    left = j + len;
                }
            }
        }
        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王蒟蒻

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值