栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

数据结构与算法——递归、回溯与分治汇总整理

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

数据结构与算法——递归、回溯与分治汇总整理

目录

预备知识:递归函数与回溯算法例1-a:求子集(medium)(回溯法、位运算法)例1-b:求子集2(medium)(回溯法)例1-c:组合数之和2(medium)(回溯法、剪枝)例2:生成括号(medium)(递归设计)例3:N皇后(hard)(回溯法)预备知识:分治算法与归并排序例4:逆序数(hard)(分治法、归并排序应用)

预备知识:递归函数与回溯算法

例1-a:求子集(medium)(回溯法、位运算法)


class Solution {
public:
    vector> subsets(vector& nums) {
        std::vector> result;//存储最终结果的result
        std::vector item;//回溯时产生各个子集的数组
        result.push_back(item);//将空集放入result
        generate(0, nums, item, result);
        return result;
    }
private:
    void generate(int i, std::vector& nums, 
    	std::vector& item, 
    	std::vector>& result) {
        if (i >= nums.size()) {
            return;
        }
        item.push_back(nums[i]);
        result.push_back(item);
        generate(i + 1, nums, item, result);
        item.pop_back();
        generate(i + 1, nums, item, result);
    }
};
例1-b:求子集2(medium)(回溯法)


在上一题的基础上扩大了条件,nums中可包含重复值。所带来的问题:

方案,先排序,在用set去重:

class Solution {
public:
    vector> subsetsWithDup(vector& nums) {
        std::vector> result;//存储最终结果的result
        std::vector item;//回溯时产生各个子集的数组
        std::set>res_set;//去重使用的集合
        std::sort(nums.begin(), nums.end());//排序
        result.push_back(item);//将空集放入result
        generate(0, nums, item, result, res_set);
        return result;
    }
private:
    void generate(int i, std::vector& nums, std::vector& item, std::vector>& result, std::set>& res_set) {
        if (i >= nums.size()) {
            return;
        }
        item.push_back(nums[i]);
        if (res_set.find(item) == res_set.end()) {
            result.push_back(item);
            res_set.insert(item);
        }
        generate(i + 1, nums, item, result, res_set);
        item.pop_back();
        generate(i + 1, nums, item, result, res_set);
    }
};
例1-c:组合数之和2(medium)(回溯法、剪枝)

class Solution {
public:
    vector> combinationSum2(vector& candidates, int target) {
        std::vector> result;//存储最终结果的result
        std::vector item;//回溯时产生各个子集的数组
        std::set>res_set;//去重使用的集合
        std::sort(candidates.begin(), candidates.end());//排序
        generate(0, candidates, item, result, res_set, 0, target);
        return result;
    }
private:
    void generate(int i, std::vector& nums, std::vector& item, std::vector>& result, std::set>& res_set, int sum, int target) {
        if (i >= nums.size() || sum > target) {
            return;
        }
        sum += nums[i];
        item.push_back(nums[i]);
        if (target == sum && res_set.find(item) == res_set.end()) {
            result.push_back(item);
            res_set.insert(item);
        }
        generate(i + 1, nums, item, result, res_set, sum, target);
        sum -= nums[i];
        item.pop_back();
        generate(i + 1, nums, item, result, res_set, sum, target);
    }
};
例2:生成括号(medium)(递归设计)


class Solution {
public:
    vector generateParenthesis(int n) {
        vector result;
        generate("", n, n, result);
        return result;
    }
private:
    void generate(string item, int left, int right, vector& result) {
        if (left == 0 && right == 0) {
            result.push_back(item);
            return;
        }
        if (left > 0) {
            generate(item + '(', left - 1, right, result);
        }
        if (left < right) {
            generate(item + ')', left, right - 1, result);
        }
    }
};
例3:N皇后(hard)(回溯法)

力扣—— 51. N 皇后

预备知识:分治算法与归并排序 例4:逆序数(hard)(分治法、归并排序应用)

力扣——315. 计算右侧小于当前元素的个数

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/743545.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号