LeetCode 回溯 全排列

2022-08-20 09:45:08 字數 1410 閱讀 9246

給定乙個 沒有重複 數字的序列,返回其所有可能的全排列。

示例:

輸入: [1,2,3]

輸出:[

[1,2,3],

[1,3,2],

[2,1,3],

[2,3,1],

[3,1,2],

[3,2,1]

]

使用回溯來做。回溯也是在模擬人做排列的方法。例如做[1,2,3]的排列:

第一步有3個數[1,2,3]可以選,先選1,此時結果為[1];

接下來還有兩個數[2,3]可以選,先放2,此時結果為[1,2];

接下來還有乙個數[3]可以選,選3,此時結果為[1,2,3],結果的長度等於數字的個數,說明找到了乙個排列。

回到第2步,有兩個數[2,3]可以選,這一次選3,結果為[1,3];

接下來還有乙個數[2]可選,選2,結果為[1,3,2],結果的長度等於數字的個數,說明找到了乙個排列。

以1開頭的排列已經搜尋結束;回到第1步,有3個數可以選,這一次選[2],結果為[2];

使用類似[1]開頭的步驟即可(步驟2到步驟5).

上面的過程可以畫成一棵樹:

該圖來自於這篇文章。回溯就是從樹的深層返回到淺層的過程,通過返回淺層,我們可以嘗試不同的結果。在做排列的過程中,比如從[1,2,3]中新增1到排列中,那在下一步中1就不能選了,所以還需要乙個visit陣列來標記乙個數字是否已經被新增到了排列當中。**如下:

class solution };

vectortrack;

vectorvisit(nums.size(), 0);

dfs(nums, 0, track, visit);

return ans;

}void dfs(vectornums, int start, vectortrack, vectorvisit)

for(int i=0; i其實上面的**的dfs函式是不需要start引數的,因為每次都是從陣列頭開始迭代,這樣寫是為了和子集這題的寫法保持一致,也便於比較。去掉start的寫法:

class solution };

vectortrack;

vectorvisit(nums.size(), 0);

dfs(nums, track, visit);

return ans;

}void dfs(vectornums, vectortrack, vectorvisit)

for(int i=0; i子集這一題和求全排列的這題很像,也是使用回溯,但也有區別。把這兩題做了,想透了,我覺得應該能對回溯有更清晰的理解。

LeetCode 全排列 回溯

傳送門 給定乙個沒有重複數字的序列,返回其所有可能的全排列。示例 輸入 1,2,3 輸出 1,2,3 1,3,2 2,1,3 2,3,1 3,1,2 3,2,1 參考官方題解 時間複雜度是 o k 1n p n,k o sum p n,k o k 1 n p n,k p n k n n k n n ...

LeetCode 全排列II(回溯法)

給定乙個可包含重複數字的序列,返回所有不重複的全排列。示例 輸入 1,1,2 輸出 1,1,2 1,2,1 2,1,1 思路分析 請先參考 leetcode 全排列 的解法。第一種方法 利用set容器中 元素的唯一性 進行去重。第二種方法 修改為set容器 class solution void d...

leetcode 46 全排列(回溯)

給定乙個沒有重複數字的序列,返回其所有可能的全排列。示例 輸入 1,2,3 輸出 1,2,3 1,3,2 2,1,3 2,3,1 3,1,2 3,2,1 核心的遞迴部分如下 for begin in range 0 n for i in range begin,n swap nums begin n...