前言
深度优先搜索(DFS)和回溯法是解决复杂问题中不可或缺的算法工具,尤其在组合问题(如全排列、子集等)中,发挥着至关重要的作用。通过递归的方式,DFS 能够遍历问题的解空间,而回溯法则通过撤销不合法的选择,避免重复计算,提高效率。在解题过程中,剪枝是优化回溯法的重要手段,它通过提前排除无效路径,进一步减少了运算的复杂度。本文将深入探讨如何使用 DFS、回溯法及剪枝技术,构建解决全排列和子集问题的决策树,并优化算法的执行效率。
一、全排列
题目链接:https://leetcode.cn/problems/permutations/description/
核心思路
这段代码实现了生成一个数组的所有排列(Permutation),并返回所有可能的排列列表。采用了**深度优先搜索(DFS)**的方式,配合一个 check 数组来记录哪些元素已经使用过,从而避免重复使用。
实现步骤
- 初始化变量:
vector<vector<int>> ret:存储最终结果,包含所有排列。vector<int> path:存储当前正在构造的排列。bool check[7]:标记数组,记录某个位置是否已经被使用,避免重复选择。默认全为false。
- 主函数
permute:- 调用
dfs(nums)开始进行递归遍历,寻找所有排列。 - 返回最终结果
ret。
- 调用
- 辅助函数
dfs:- 递归终止条件:当
path的长度等于nums.size(),说明已经构造出一个完整的排列,将其加入结果集ret。 - 循环遍历:
- 遍历数组的每个元素,判断其是否已经被使用(
check[i] == false)。 - 如果未使用,将其加入当前路径
path,同时更新check[i] = true。 - 递归调用
dfs(nums),继续构造排列。 - 回溯:
- 移除当前路径中的最后一个元素
path.pop_back()。 - 重置
check[i] = false,允许后续尝试其他路径。
- 移除当前路径中的最后一个元素
- 遍历数组的每个元素,判断其是否已经被使用(
- 递归终止条件:当
代码
class Solution {
public:
vector<vector<int>> ret;
vector<int> path;
bool check[7];
vector<vector<int>> permute(vector<int>& nums) {
dfs(nums);
return ret;
}
{
(path.() == nums.()) {
ret.(path);
;
}
( i = ; i < nums.(); i++) {
(check[i] == ) {
path.(nums[i]);
check[i] = ;
(nums);
path.();
check[i] = ;
}
}
}
};


