【递归、搜索和回溯】穷举vs暴搜vs深搜vs回溯vs剪枝
个人主页 : zxctscl
专栏 【C++】、 【C语言】、 【Linux】、 【数据结构】、 【算法】
如有转载请先通知
文章目录
- 前言
- 1 46. 全排列
- 1.1 分析
- 1.2 代码
- 2 78. 子集
- 2.1 分析
- 2.2 代码
前言
之前提到递归、搜索和回溯介绍: 【递归、搜索和回溯】递归、搜索和回溯介绍及递归类算法例题,继续来看着类型的题目
1 46. 全排列
1.1 分析
穷举也就是枚举
- 画决策树:越详细越好
当情况不符合的时候就剪枝
- 设计代码
(1)全局变量
需要记录的东西
二维数组int[][] ret
来记录结果,用int[] path
记录路径
用一个布尔类型数组bool[] check
,来判断这个路径下标对应的数是否使用过,就实现了剪枝。
枚举1的时候在check里面查看是否已经用了,
(2)dfs函数
仅需关心,每一个节点该干什么事情。
细节:
回溯:(1)path
向上走的时候,减掉最后一个元素;(2)path
去掉最后一个元素时候,最后一个元素把check
修改为flase
。
剪枝:check实现
递归出口:遇到叶子结点,直接添加结果。
1.2 代码
class Solution {vector<vector<int>> ret;vector<int> path;bool check[7];
public:vector<vector<int>> permute(vector<int>& nums) {dfs(nums);return ret;}void dfs(vector<int>& nums){if(nums.size()==path.size()){ret.push_back(path);return;}for(int i=0;i<nums.size();i++){if(check[i]==false){path.push_back(nums[i]);check[i]=true;dfs(nums);//恢复现场path.pop_back();check[i]=false;}}}
};
2 78. 子集
2.1 分析
解法一:
-
决策树
×表示不选,√表示选
-
设计代码
全局变量:(1)用int[] path
来记录路径2)用int[][] ret
存放最终结果
dfs函数:
dfs(nums,i)
传入数组,i位置选还是不选;
选:path±nums[i];再去下一层dfs(nums,i+1)
不选:直接去下一层dfs(nums,i+1)
细节问题:
剪枝
回溯:在选择到时候path-=nums[i]
递归出口:到叶子结点时候i==nums.size()
解法二:
-
决策树
看子集元素个数,要么0个,要么一个,要么两个,只从元素后面开始选择
刚开始就是空集
一个元素有:1,2,3
两个元素,再一个元素基础上添加一个
三个元素,再两个元素基础上添加一个
-
设计代码
全局变量:(1)用int[] path
来记录路径 (2)用int[][] ret
存放最终结果
dfs函数:
dfs(nums,pos)从pos位置开始;
for(i=pos;i<nums.size();i++)
{path+nums[pos];dfs(nums,i+1);path-最后一个元素}
细节问题:
剪枝
回溯:
递归出口:没有递归出口
2.2 代码
解法一:
class Solution {vector<vector<int>> ret;vector<int> path;
public:vector<vector<int>> subsets(vector<int>& nums) {dfs(nums,0);return ret;}void dfs(vector<int>& nums,int pos){if(pos==nums.size()){ret.push_back(path);return;}//选path.push_back(nums[pos]);dfs(nums,pos+1);path.pop_back();//不选dfs(nums,pos+1);}
};
解法二:
class Solution {vector<vector<int>> ret;vector<int> path;
public:vector<vector<int>> subsets(vector<int>& nums) {dfs(nums,0);return ret;}void dfs(vector<int>& nums,int pos){ret.push_back(path);for(int i=pos;i<nums.size();i++){path.push_back(nums[i]);dfs(nums,i+1);path.pop_back();}}
};
有问题请指出,大家一起进步!!!