給定一個不含重複數字的數組 nums ,返回其 全部可能的全排列 。你能夠 按任意順序 返回答案。javascript
示例 1:java
輸入: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]]
複製代碼
提示:markdown
1 <= nums.length <= 6
-10 <= nums[i] <= 10
複製代碼
回溯法(backtracking)是優先搜索的一種特殊狀況,又稱爲試探法,經常使用於須要記錄節點狀態的深度優先搜索。一般來講,排列、組合、選擇類問題使用回溯法比較方便。 顧名思義,回溯法的核心是回溯。在搜索到某一節點的時候,若是咱們發現目前的節點(及其子節點)並非需求目標時,咱們回退到原來的節點繼續搜索,而且把在目前節點修改的狀態 還原。spa
這樣的好處是咱們能夠始終只對圖的總狀態進行修改,而非每次遍歷時新建一個圖來儲存 狀態。 在具體的寫法上,它與普通的深度優先搜索同樣,都有 [修改當前節點狀態]→[遞歸子節 點] 的步驟,只是多了回溯的步驟,變成了 [修改當前節點狀態]→[遞歸子節點]→[回改當前節點 狀態]。 回溯法。有兩個小訣竅,一是按引用傳狀態,二是全部的狀態修 改在遞歸完成後回改。 回溯法修改通常有兩種狀況,一種是修改最後一位輸出,好比排列組合;一種是修改訪問標 記,好比矩陣裏搜字符串。code
怎樣輸出全部的排列方式呢?對於每個當前位置 i,咱們能夠將其於以後的任意位置交換, 而後繼續處理位置 i+1,直處處理到最後一位。爲了防止咱們每此遍歷時都要新建一個子數組儲 存位置 i 以前已經交換好的數字,咱們能夠利用回溯法,只對原數組進行修改,在遞歸完成後再 修改回來。 咱們以樣例[1,2,3]爲例,按照這種方法,咱們輸出的數組順序爲[[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1]],能夠看到全部的排列在這個算法中都被考慮到了。orm
/** * @param {number[]} nums * @return {number[][]} */
var permute = function(nums) {
let ans = [];
let start = 0, len = nums.length, _start = 0;
backtracking(nums, start, ans);
return ans;
};
const backtracking = function(_nums, level, ans) {
if(level === _nums.length - 1) {
ans.push([..._nums]);
return;
}
for(let i = level; i < _nums.length; i++) {
[_nums[i], _nums[level]] = [_nums[level], _nums[i]] // 修改當前節點狀態
backtracking(_nums, level + 1, ans); // 遞歸子節點
[_nums[i], _nums[level]] = [_nums[level], _nums[i]] // 恢復當前節點狀態
}
}
複製代碼