今天的题算比较难。
39.组合总和
不会。唉,看了讲解其实跟前面的就只有一点区别,结果自己把逻辑想的那么复杂。
40.组合总和 II
看了参考解法,我的解法更简洁,感觉也更好理解,通过画树形结构分析出来的,当然也要学习一下used这种标记方法。以下是我的解法(关键在于while循环):
for (int i = index; i < candidates.size() && sum + candidates[i] <= target; i++) {
path.push_back(candidates[i]);
sum += candidates[i];
backtracking(candidates, target, i + 1);
sum -= candidates[i];
path.pop_back();
while (i < candidates.size() - 1 && candidates[i+1] == candidates[i]) i++;
}
131.分割回文串
写了很久,大概也许应该算写出来了吧,虽然运行了800+ms,只打败了5%的人。。。
这道题其实挺难,参考解法最难想到的点是:切割的起始位置和终止位置到底是哪个?起始是index终止才是i,这样就可以实现此功能:在同一层递归函数上,index是不变量,也就是切割的起始位置不变,变的是终止位置,于是可以检查同一起点不同终点的字符子串回文情况。
而我解法运行时间这么长是因为:切割起始位置是i,终止位置是位于i后面的j,i和j的移动可以得到不同长度的字串,但是由于在同一层递归上起始位置的不断变化,导致得到的path不一定是从原始字符串起点开始的,所以最终需要判断path里字符子串总长度跟原字符串长度是否一致。
最最关键点:什么是在同一层递归函数里的不变量?什么是变量?
class Solution {
public:
vector<string> path;
vector<vector<string>> result;
void backTracking(string& s, int index) {
if (index == s.size()) {
int size = 0;
for (string ss : path) size += ss.size();
if (size == s.size()) result.push_back(path);
return;
}
for (int i = index; i < s.size(); i++) {
for (int j = i + 1; j <= s.size(); j++) {
string subs(s.begin() + i, s.begin() + j);
string revs = subs;
reverse(revs.begin(), revs.end());
if (revs == subs) {
path.push_back(subs);
backTracking(s, j);
path.pop_back();
}
}
}
return;
}
vector<vector<string>> partition(string s) {
backTracking(s, 0);
return result;
}
};
588

被折叠的 条评论
为什么被折叠?



