leetcode30 串联所有单词的子串

先对words中的单词排列组合,然后对s滑窗操作;部分样例超时,代码如下:
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
//dfs找出words所有组合,然后在s滑窗
//排除异常情况
int len=0;
for(auto w:words){
len+=w.size();
}
if(len==0 || s.size()==0 || len>s.size()) return {};
//排列组合words
set<string> s_words;
vector<int> indexs;
for(int i=0;i<words.size();i++){
indexs.push_back(i);
}
do{
string tmp="";
for(int i=0;i<indexs.size();i++){
tmp+=words[indexs[i]];
}
s_words.insert(tmp);
}while(next_permutation(indexs.begin(),indexs.end()));
//在s中滑窗寻找起始位置,O(m*n*k) m为s长度,n为s_words字符串个数,k为subs的长度;
vector<int> res;
for(int i=0;i<=s.length()-len;i++){
string subs=s.substr(i,len);
if(s_words.find(subs)!=s_words.end()){
res.push_back(i);
}
}
return res;
}
};
下面也超时,均执行至148/173
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
//dfs找出words所有组合,然后在s滑窗
//排除异常情况
int len=0;
for(auto w:words){
len+=w.size();
}
if(len==0 || s.size()==0 || len>s.size()) return {};
//排列组合words
set<string> s_words;
vector<int> indexs;
for(int i=0;i<words.size();i++){
indexs.push_back(i);
}
do{
string tmp="";
for(int i=0;i<indexs.size();i++){
tmp+=words[indexs[i]];
}
s_words.insert(tmp);
}while(next_permutation(indexs.begin(),indexs.end()));
//在s中滑窗寻找起始位置,O(m*n*k) m为s长度,n为s_words字符串个数,k为subs的长度;
vector<int> res;
for(int i=0;i<=s.length()-len;i++){
string subs=s.substr(i,len);
for(auto it=s_words.begin();it!=s_words.end();it++){
string tmp=*it;
int flag=1;
for(int j=0;j<len;j++){
if(tmp[j]!=subs[j]){
flag=0;break;
}
}
if(flag==1) {
res.push_back(i);break;
}
}
}
return res;
}
};
想办法对暴力算法进行提速,
以下为别人的提速方案,可行;
作者:Xdo
链接:https://leetcode-cn.com/problems/substring-with-concatenation-of-all-words/solution/bao-li-suan-fa-jia-ru-qu-zhong-you-hua-10bei-ti-su/
思路就是,先把存在的字符串,放到 hashmap ,可以快速比较,然后每一个位置都进行匹配
但这里会有很多的重复计算,就可以使用一个小技巧,先计算目标串的每个字母的 ASCII 和,
然后和当前要匹配的字符串的每个字母的 ASCII 进行比较,如果不相等就不用进行下面的匹配过程了
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
vector<int> res;
if(words.size()<1 || s.size()<1 || s.size() < words[0].size()*words.size()) return res;
int wordLen = words[0].size(), lens = wordLen*words.size(), target = 0, cur = 0;
unordered_map<string,int> allWord;
for(auto& it:words){
allWord[it]++;
for(auto& i:it) target += i;
}
for(int i=0; i<lens; i++) cur += s[i];
// 先看当前字符串的 ASCII 码相加是否相等 方便去重
for(int i=0, j; i<=s.size()-lens; cur -= s[i], cur += s[lens + i++]){
// 快速去重
if(cur != target) continue;
// 确认一下,是否为真的匹配
unordered_map<string,int> tem(allWord);
for(j=i; j<i+lens; j+=wordLen)
if(tem[s.substr(j, wordLen)]-- == 0) break;
if(j == i+lens) res.push_back(i);
}
return res;
}
};
leetcode30 串联所有单词的子串的更多相关文章
- [LeetCode] 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 sta ...
- 【LeetCode-面试算法经典-Java实现】【030-Substring with Concatenation of All Words(串联全部单词的子串)】
[030-Substring with Concatenation of All Words(串联全部单词的子串)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 Yo ...
- [LeetCode] 30. 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 sta ...
- Java实现 LeetCode 30 串联所有单词的子串
30. 串联所有单词的子串 给定一个字符串 s 和一些长度相同的单词 words.找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置. 注意子串要与 words 中的单词完全匹配, ...
- [LeetCode] 30. 串联所有单词的子串
题目链接: https://leetcode-cn.com/problems/substring-with-concatenation-of-all-words/ 题目描述: 给定一个字符串 s 和一 ...
- Leetcode 30 串联所有单词的子串 滑动窗口+map
见注释.滑动窗口还是好用. class Solution { public: vector<int> findSubstring(string s, vector<string> ...
- 【LeetCode 30】串联所有单词的子串
题目链接 [题解] 开个字典树记录下所有的单词. 然后注意题目的已知条件 每个单词的长度都是一样的. 这就说明不会出现某个字符串是另外一个字符串的前缀的情况(除非相同). 所以可以贪心地匹配(遇到什么 ...
- [Swift]LeetCode30. 与所有单词相关联的字串 | 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 sta ...
- #leetcode刷题之路30-串联所有单词的子串
给定一个字符串 s 和一些长度相同的单词 words.找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置.注意子串要与 words 中的单词完全匹配,中间不能有其他字符,但不需要考 ...
随机推荐
- Spring中事务的传播行为,7种事务的传播行为,数据库事务的隔离级别
Propagation.REQUIRED 代表当前方法支持当前的事务,且与调用者处于同一事务上下文中,回滚统一回滚(如果当前方法是被其他方法调用的时候,且调用者本身即有事务),如果没有事务,则自己新建 ...
- 如何从零搭建hexo个人博客网站
https://www.jianshu.com/p/adf65cbad393?utm_source=oschina-app 准备工作 github账号 node.js 环境搭建 git使用 mar ...
- springboot无法获取证书内容
最近项目里面在接第三方验证的时候,需要用到生成的公钥和私钥证书.在demo测试的时候,发现在resources里面直接建立一个key文件夹放入证书文件,然后使用文件方式去获取,大概代码如下: File ...
- 中国大学MOOC课程信息爬取与数据存储
版权声明:本文为博主原创文章,转载 请注明出处: https://blog.csdn.net/sc2079/article/details/82016583 10月18日更:MOOC课程信息D3.js ...
- 树的总结(遍历,BST,AVL原型,堆,练习题)
目录 树 一.抽象数据类型 二.二叉树的性质 三.二叉树的遍历 三.活用树的遍历 四.BST树 五.AVL树 六.BST树和AVL树练习 七.堆 树 @ 一.抽象数据类型 1.顺序存储 使用数组存储 ...
- 使用Barrier分三步将大象放入冰箱
class Program { //构造大象和冰箱 private static ElephantsAndFridges elephantsAndFridges = new ElephantsAndF ...
- HTML5 离线缓存manifest
1.简介W3C官方对manifest的介绍是HTML5 引入了应用程序缓存,这意味着 web 应用可进行缓存,并可在没有因特网连接时进行访问. 应用程序缓存为应用带来三个优势: 离线浏览 - 用户可在 ...
- Linux文件系统之mv(重命名/移动文件)
mv(move)命令 输入man mv,了解到mv命令是用于移动或重命名文件 语法 mv [options] source dest mv [options] source... directory ...
- Codeforces Round #590 (Div. 3) C. Pipes
链接: https://codeforces.com/contest/1234/problem/C 题意: You are given a system of pipes. It consists o ...
- CodeForces 837F - Prefix Sums | Educational Codeforces Round 26
按tutorial打的我血崩,死活挂第四组- - 思路来自FXXL /* CodeForces 837F - Prefix Sums [ 二分,组合数 ] | Educational Codeforc ...