搜索(Search)

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 += " ";
    }   
    // 遍历
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值