Example:
Input: [1,2,3]
Output:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
典型求排列组合,该题思路非常重要,考题非常常见。大家一定要掌握DFS(深度搜索)法,也叫做递归法,回溯法求解。因为DFS能够穷举所有情况,达到求解所有可能解的要求。八皇后问题也是经典的DFS问题。
解题思路:
因为求所有排列组合,自然想到DFS,因为递归能够穷举所有情况,而递归重要的是由结束条件,以免进入死循环。本题一共设置了3个全局变量,含义见注释。
结束条件:example.size() == nums.size(),代表一种排列组合依据产生;最后一行再加一个return,作为函数出口;
核心逻辑:若nums[i]未被访问,则加入当前的排列example,设为已访问,通过DFS递归加入其他元素的排列;
然后重新将nums[i]设置为未访问,从当前排列中删除,为的就是调整其在排列组合中的位置,搜索其他情况。
本代码产生排列组合的顺序就是和output一样。
java版本
class Solution {
List<List<Integer>> result = new ArrayList<>();
List<Integer> example = new ArrayList<>();
boolean[] visit;
void DFS(int[] nums){
if(example.size() == nums.length){
List<Integer> e = new ArrayList<>();
for(Integer n: example){
e.add(n);
}
result.add(e);
return;
}
for(int i = 0;i < nums.length;i++){
if(visit[i] == false){
example.add(nums[i]);
visit[i] = true;
DFS(nums);
example.remove(example.size() - 1);
visit[i] = false;
}
}
return;
}
public List<List<Integer>> permute(int[] nums) {
visit = new boolean[nums.length];
DFS(nums);
return result;
}
}
c++版本
class Solution {
public:
vector<vector<int>> result; //返回结果
vector<int> example; //一种排列组合,如[1,2,3]
vector<bool> visit; //访问标志
void DFS(vector<int> nums){
if(example.size() == nums.size()){ //搜索结束状态
result.push_back(example);
return;
}
for(int i = 0;i < nums.size();i++){
if(!visit[i]){ //未被访问
example.push_back(nums[i]);
visit[i] = true; //设为已访问
DFS(nums); //递归搜索
//为了搜索更多排列组合,将这个元素删除,并重新设为未访问
example.pop_back();
visit[i] = false;
//之前多加了下面这行,进入了死循环
//DFS(nums); //递归搜索
}
}
return;
}
vector<vector<int>> permute(vector<int>& nums) {
vector<bool> a(nums.size(), false); //初始化访问标志
visit = a;
DFS(nums); //开始搜索
return result;
}
};
本小白华中科技大学在读研究生,自然语言处理方向。现每日一更LeetCode Top 100 Liked Questions, 旨在于通过通俗易懂的画风和诸位计算机朋友们一起成长呀,不局限某题,争取举一反三,所有Questions均呈上C++和Java解法,不足之处多多指正,共同学习。