您的位置:首页 > 其它

LeetCode Substring with Concatenation of All Words

2014-03-22 14:41 357 查看
class Solution {
public:
vector<int> findSubstring(string S, vector<string> &L) {
vector<int> res;
unordered_map<string, int> stat;
unordered_map<string, int> run;
int len = S.size();
int num = L.size();
int per = 0;

if (num == 0 || !(per = L[0].size())) return res;

int part= num * per;
if (part > len) return res;

int end = len - part;
unordered_map<string, int>::iterator iter;
pair<unordered_map<string, int>::iterator, bool> ir;

for (int i=0; i<num; i++) {
ir = stat.insert(pair<string, int>(L[i], 1));
if (ir.second == false){
ir.first->second++;
}
}

int i, j, pos, wc;
string pre;
for (i=0; i<=end; i++) {
pos = i;
for (j=0; j<num; j++, pos += per) {
string seg = S.substr(pos, per);
if (j == 0 || seg != pre) {
iter = stat.find(seg);
if (iter == stat.end()) break;
wc = iter->second;
ir = run.insert(pair<string, int>(seg, 1));
iter = ir.first;
if (ir.second) {
pre = seg;
continue;
}
}
iter->second++;
if (wc < iter->second) break;
}
if (j == num) res.push_back(i);
run.clear();
}
return res;
}
};


暴力解,跑了500+ms,如果每次都这样把题目应付过去,显然做题没有意义了。于是看Leetcode上关于那题的discuss,有人说可以用解决Minimum Window Substring的方法来解这一题,的确是可以。又搜了份Java实现的代码,一跑竟然也可以达到500ms,看来两种方法效率的确差很多。下面给出自己实现的代码

class Solution3 {
public:
vector<int> findSubstring(string S, vector<string> &L) {
vector<int> res;
unordered_map<string, int> stat;
unordered_map<string, int> run;
int len = S.size();
int num = L.size();
int per = 0;

if (num == 0 || !(per = L[0].size())) return res;

int part = num * per;
if (part > len) return res;

unordered_map<string, int>::iterator iter;
pair<unordered_map<string, int>::iterator, bool> ir;

for (int i = 0; i < num; i++) {
ir = stat.insert(pair<string, int>(L[i], 0));
ir.first->second++;
}
int wc;
for (int i = 0; i < per; i++) {
int step = 0;
run.clear();
// scan like a worm, string[spos, epos] is the candidate
int spos=i, epos = i + per - 1;
for (; epos < len; epos += per) {
string seg = S.substr(epos - per + 1, per);
iter = stat.find(seg);
// encounter some word not in L
if (iter == stat.end()) {
spos = epos + 1;
step = 0;
run.clear();
continue;
}

wc = iter->second;
step++;

ir = run.insert(pair<string, int>(seg, 0));
iter = ir.first;
iter->second++;

// string[spos, epos] is matched
if (iter->second == wc && step == num) {
res.push_back(spos);
run.find(S.substr(spos, per))->second--;
step--;
spos += per;
continue;
}

// number of duplicated word exceeds needed
if (iter->second > wc) {
string tmp = S.substr(spos, per);
// find the first duplicated one
while(seg != tmp) {
run.find(tmp)->second--;
step--;
spos += per;
tmp = S.substr(spos, per);
}
// then skip it
iter->second--;
spos += per;
step--;
}
}
}
return res;
}
};


跑了一下在100+ms左右,又习得一策略技能!

参考:

zhuli题解 http://www.cnblogs.com/zhuli19901106/p/3570539.html
java实现 https://github.com/shengmin/coding-problem/blob/master/leetcode/substring-with-concatenation-of-all-words/Solution.java
leetcode资料 http://leetcode.com/2010/11/finding-minimum-window-in-s-which.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: