LeetCode——Hot 100【全排列】
题目
题目链接:全排列
题目分析
全排列问题是指,给定一个不含重复数字的数组,生成其所有可能的排列组合。例如,数组 [1,2,3]
的全排列有 [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
这些情况。
解题思路
本题采用回溯算法来解决。回溯算法的核心思想是深度优先搜索(DFS),通过尝试所有可能的选择,在满足条件时记录结果,不满足时回退(撤销选择),继续尝试其他选择。
AC代码
class Solution {vector<vector<int>> ret;bool check[7];vector<int> path;public:void dfs(vector<int> nums) {if (path.size() == nums.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;}}}vector<vector<int>> permute(vector<int>& nums) {dfs(nums);return ret;}
};
代码详解
- 成员变量定义
vector<vector<int>> ret
:用于存储最终所有的全排列结果。bool check[7]
:长度为 7 的布尔数组(因为题目中提示数组长度不超过 6),用于标记数组中的元素是否已经被使用到当前的排列路径中。vector<int> path
:用于存储当前正在构建的排列路径。
dfs
函数- 函数作用:深度优先搜索生成全排列。
- 终止条件:当
path
的长度等于输入数组nums
的长度时,说明已经生成了一个完整的全排列,将当前path
复制一份添加到ret
中,然后返回。 - 遍历与选择:遍历输入数组
nums
中的每个元素,如果该元素未被使用(check[i] == false
),则将其标记为已使用(check[i] = true
),添加到当前路径path
中,然后递归调用dfs
函数继续生成下一个位置的元素。 - 回溯操作:递归返回后,进行回溯,将该元素从
path
中移除(path.pop_back()
),并标记为未使用(check[i] = false
),以便其他排列路径可以使用该元素。
示例:(以 nums = [1,2,3]
为例)
- 初始时,
path
为空,check
数组全为false
。 - 第一次调用
dfs
,遍历到i = 0
(元素1
),check[0]
设为true
,path
变为[1]
,递归调用dfs
。 - 在递归的
dfs
中,path
长度为 1,继续遍历。遍历到i = 1
(元素2
),check[1]
设为true
,path
变为[1,2]
,递归调用dfs
。 - 再次递归的
dfs
中,path
长度为 2,继续遍历。遍历到i = 2
(元素3
),check[2]
设为true
,path
变为[1,2,3]
,此时path
长度等于nums
长度(3),将[1,2,3]
加入ret
。然后回溯,path
弹出3
,check[2]
设为false
。 - 回到上一层,继续遍历
i = 2
之后的元素(无),再回溯,path
弹出2
,check[1]
设为false
。 - 继续在这一层遍历
i = 2
(元素3
),check[2]
设为true
,path
变为[1,3]
,递归调用dfs
,后续生成[1,3,2]
并加入ret
,以此类推,最终生成所有全排列。
总结
该代码通过回溯算法,深度优先地遍历所有可能的排列情况,成功生成了数组的全排列,逻辑清晰,是解决全排列问题的经典方法。