search
bfs 和 dfs的相关的题目
1. 全排列
题目: 给定一个数字列表,返回其所有可能的排列。
// premute(ans, nums, 0)
void permute(vector<vector<int> > &ans, vector<int> &nums, int k){
if(k==nums.size()-1){
ans.push_back(nums);
}
// 以k开头的所有排列
for(int i=k;i<nums.size();i++){
// 以每一个都作为开头,进行遍历
swap(nums[i],nums[k]);
permute(ans,nums,k+1);
// 回溯
swap(nums[i],nums[k]);
}
}
2. 子集
题目: 给定一个可能具有重复数字的列表,返回其所有可能的子集。
// 调用函数dfs(res, sub, , nums, 0)之前, nums 必须首先排序,
// sort(nums.begin(), nums.end());
void dfs(vector<vector<int>> &res, vector<int> &sub, vector<int> &nums, int k) {
res.push_back(sub);
for(int i= k; i < nums.size(); i++) {
// 跳过相同元素,
if(i != k && nums[i] == nums[i - 1]) continue;
sub.push_back(nums[i]);
dfs(res, sub, nums, i + 1);
// 回溯其他可能组合
sub.pop_back();
}
}
3. Word Break Problem
题目: 给一字串s和单词的字典dict,在字串中增加空格来构建一个句子,并且所有单词都来自字典。返回所有有可能的句子。
分析: 利用f[i]记录以i为起点的每个片段的终点j,并且片段要在字典中,然后从0位置开始搜索,每次给当前片段加上空格,然后以当前片段的末尾作为下一次搜索的头部,避免不必要的搜索。
vetor<int> f[1000];
vector<string> wordBreak(string &s, unordered_set<string> &wordDict) {
n = s.length();
int i, j;
// 遍历所有可能的(i,j)组合,是否在字典中
for (i = n - 1; i >= 0; --i) {
for (j = i + 1; j <= n; ++j) {
if (wordDict.find(s.substr(i, j - i)) != wordDict.end()) {
// 大家请思考不加这个条件和加条件有什么区别,
// if (j == n || f[j].size() > 0)
// f[i].push_back(j);
f[i].push_back(j);
}
}
}
dfs(0, s, "");
return res;
}
void dfs(int p, string s, string &now, vector<int> &res) {
if(p == s.size()) {
res.push_back(now);
return;
}
if(p > 0) { // 找到一个单词划分
now += " ";
}
// 遍历