給定乙個 沒有重複 數字的序列,返回其所有可能的全排列。
示例:
思路:回溯法問題用遞迴求解,可以聯絡上樹的遍歷,我們可以將決策路徑畫成一棵樹,回溯的過程就是這棵樹的遍歷過程。
回溯問題關於已選集合和候選集合,例如下圖,在進行第一次選擇時,全部的 3 個數都可以選擇,候選集合的大小為 3。在第二次選擇時,候選集合的大小就只有 2 了;第三次選擇時,候選集合只剩乙個元素。可以看到,全排列問題候選集合的變化規律是:每做一次選擇,候選集合就少乙個元素,直到候選集合選完為止。
我們可以用樹形結構來表示,即執行一次深度優先遍歷,從樹的根結點到葉子結點形成的路徑就是乙個全排列。
這棵樹除了根結點和葉子結點以外,每乙個結點做的事情其實是一樣的,即在已經選了一些數的前提,我們需要在剩下還沒有選擇的數中按照順序依次選擇乙個數,這顯然是乙個遞迴。
在對樹的遞迴過程中:
(1)狀態指的是每乙個結點在求解問題時的不同階段;
(2)深度優先遍歷有「回頭」的過程,在「回頭」以後,狀態變數需要設定成為和先前一樣,需要撤銷上一次選擇,所以深度優先遍歷再回到上一層結點時需要「狀態重置」;
(3)在深度優先遍歷過程中,我們可以直接借助系統棧空間,為我們儲存所需要的狀態變數。可以設定乙個變數path,path表示已經選哪些數。往下走一層的時候,path 變數在尾部追加,而往回走的時候,需要撤銷上一次的選擇,也是在尾部操作,因此 path 變數是乙個棧;
(4)我們還需要兩個狀態變數,表示搜尋全排列問題的不同階段:
1.已經選了哪些數,到葉子結點時候,這些已經選擇的數就構成了乙個全排列;
2.乙個布林陣列 used,表示當前考慮的數字是否在path變數裡。初始化的時候都為 false 表示這些數還沒有被選擇,當我們選定乙個數的時候,就將這個陣列的相應位置設定為 true ,這樣在考慮下乙個位置的時候,就能夠以 o(1)的時間複雜度判斷這個數是否被選擇過。
(5)除此之外,我們還要了解遞迴的終止條件。遞迴的終止條件是,數已經選夠了,因此我們需要乙個變數來表示當前遞迴到第幾層,我們把這個變數叫做 depth。
(6)在非葉子結點處,產生不同的分支,我們可以用乙個迴圈在還未選擇的數中依次選擇乙個元素作為下乙個位置的元素。
class
solution
backtrack
(nums, len,
0, path, used,res)
;return res;
}void
backtrack
(int
nums,
int len,
int depth,
list
path,
boolean
used,list
> res)
for(
int i =
0; i < len; i++)}
}}
(三十七)程序組
程序組就是乙個或多個程序的集合,每個程序組都有唯一的程序組id 整數,也可以存放在pid t型別中 程序組由程序組id來唯一標識,程序組id是乙個正整數,用來獲得當前程序程序組id的命令 ps ajx 顯示如下 pgid列即為程序組列 ppid pidpgid sidtty tpgid stat u...
OVS vswitchd啟動(三十七)
vswitchd是ovs中執行在使用者空間的守護程序,實現ovs主要的功能邏輯,本文將著重分析其啟動過程。在數通領域,交換機和橋很多時候可以是在說乙個東西,它工作在二層,可以新增多個埠,從乙個埠上收到的報文會根據mac表從其他某個埠 出去.在ovs中,它也還是乙個東西,不過ovs用兩個資料結構描述它...
安全駕駛 路障 三十七
路遇障礙物,寧騎不繞。2012 年4 月,我去上海,在日東高速上,有輛本地牌照的a6,時速100左右,一直騎線行駛,我在它後面,總是判斷不准他的行車意圖,後來,找準時機,我把他超了。我推測,他騎線行駛有三種可能 1 瞌睡了,他不光騎線,偶爾還在兩個車道來回切換。2 新手,日東高速上平時很少有車輛通行...