给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
示例 1:
输入: nums = [1,2,3]
输出: [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
示例 2:
输入: nums = [0,1]
输出: [[0,1],[1,0]]
示例 3:
输入: nums = [1]
输出: [[1]]
提示:
1 <= nums.length <= 6-10 <= nums[i] <= 10nums中的所有整数 互不相同
题解:
回溯法(Backtracking)是一种解决问题的算法范式,通常用于在一个大的解空间中搜索问题的所有可能解。回溯法通常在问题的解空间树上进行深度优先搜索,尝试找到问题的解。
以下是一些情况下使用回溯法的示例:
- 组合问题: 当问题要求找到满足一些条件的组合时,回溯法是一个常见的选择。例如,给定一组数,找到所有可能的组合使其和等于目标值。
- 排列问题: 类似于组合问题,回溯法也适用于排列问题。例如,给定一组数,找到所有可能的排列。
- 图的遍历: 在图的深度优先搜索中,回溯法也经常被使用。当你需要在图中搜索所有可能的路径时,回溯法是一个自然的选择。
- 棋盘问题: 回溯法在解决一些涉及到棋盘、迷宫或布局的问题时非常有效。例如,八皇后问题,数独问题等。
- 子集问题: 当你需要找到一组元素的所有可能子集时,回溯法同样是一个合适的选择。例如,给定一组数,找到所有可能的子集。
- 搜索问题: 回溯法适用于各种搜索问题,其中需要在可能的解空间中寻找一个满足条件的解。
需要注意的是,回溯法通常在问题的解空间较大且无法使用直接的数学方法求解时使用。它的思想是尝试一种选择,如果这种选择导致无法找到解,则回溯到上一步,尝试其他选择,直到找到解为止。
class Solution {
public List<List<Integer>> permute(int[] nums) {
//动态规划问题 回溯
List<List<Integer>>result=new ArrayList<>();
List<Integer>arr=new ArrayList<>();
for(int num:nums){
arr.add(num);
}
int n=nums.length;
back(n,0,arr,result);
return result;
}
public void back(int n,int first,List<Integer>arr, List<List<Integer>> result){
if(first==n)
result.add(new ArrayList<>(arr));
for(int i=first;i<n;i++){
Collections.swap(arr,i,first);
back(n,first+1,arr,result);
Collections.swap(arr,i,first);
}
}
}