46.全排列
阿新 • • 發佈:2021-06-19
46.全排列
題目
給定一個不含重複數字的陣列 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]]
來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/permutations
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。
題解
分析之後發現這道題還是在列舉所有的可能性,那麼準備採用回溯法。
抽象樹中,可以看出排列中[1,2]和[2,1]是兩種不同的選擇,而在組合中是一樣。那就不需要使用startIndex來控制。組合問題其實取數有一規律都是從前往後選,但是排序不一樣的,那麼在取值的時候就需要判斷之前的數是否被選了。
遞迴的引數和返回值
nums:輸入的陣列
path:存放單次排序的路徑
List<List<Integer>> res = new ArrayList<>(); void backtracing(int[] nums,List<Integer> path);
遞迴的終止條件
遞迴的層數是確定的,只要所有的數都排列了就結束了
if(path.size() == nums.length){
res.add(path);
return;
}
遞迴的單層邏輯
每一次取值都需要從頭到尾選擇,不能取已經取過的值,那怎麼表示值已經取過了?path的路徑之中有就說明已經取值了,沒有就說明還沒有取過值
還可以設定一個visited陣列記錄元素是否被訪問過。
for(int i =0;i<nums.length;i++){ if(path.cantains(i))continue; //表示已經取過了,那就不能去跳到下一個 path.add(i); backtracing(nums,path); path.remove(path.size()-1); }
程式碼
class Solution {
List<List<Integer>> res ;
public List<List<Integer>> permute(int[] nums) {
res = new ArrayList<>();
backtracing(nums,new ArrayList<>());
return res;
}
void backtracing(int[] nums,List<Integer> path){
if(path.size() == nums.length){
res.add(new ArrayList(path));
return;
}
for(int num:nums){
if(path.contains(num))continue;
path.add(num);
backtracing(nums,path);
path.remove(path.size()-1);
}
}
}