「回溯」相關題型

2021-10-24 02:07:50 字數 3285 閱讀 4046

列印乙個字串的全排列(比如abc的排列包括:abc,cab,cba,,,,),劍指offer38

又或者,給一串數字,求這串數字的全排列,比如:leetcode46

思路1、首先可以分成兩種情況:一種是裡面沒有重複的字元,一種是有重複的字元(只需要加乙個hashset,每次檢視需要交換的在set裡面是不是已經存在)。整體的結構是:交換其中某兩位,然後繼續遞迴後面的,然後在交換回來(恢復交換的 元素),準備迎接下一輪。

過程就如下圖所示:

public arraylist

res;

public string[

]permutation

(string s)

public

void

process

(char

chas,

int index)}}

public

void

swap

(char

chas,

int i,

int j)

思路2、用舉的第二個例子來說明。這裡不使用上面的交換來實現,而是將每種可能性組成乙個鍊錶(linkedlist),每次更新鍊錶的時候查詢鍊錶裡面存不存在這個元素,如果存在了直接跳過,示意圖如下:

public list

>

permute

(int

nums)

public

void

backtrack

(int

nums,list

> res,linkedlist

tmp )

}

給定一組不含重複元素的整數陣列 nums,返回該陣列所有可能的子集(冪集)。

說明:解集不能包含重複的子集。

思路1:首先也是類似dfs遞迴的方法,每個位置都可以選擇要,或者不要,但是需要注意的乙個點是因為我們重複利用了同乙個list,因此我們每次add之後別忘記remove

public list

>

subsets1

(int

nums)

res=

newarraylist

<

>()

;process

(nums,0,

newarraylist

());

return res;

}public

void

process

(int

arr,

int index,list

tmp)

//這裡選擇了重複利用tmp,沒有複製乙個新的放入遞迴裡面

process

(arr,index+

1,tmp)

; tmp.

add(arr[index]);

process

(arr,index+

1,tmp)

; tmp.

remove

(tmp.

size()

-1);

//因此最後需要刪除當前元素

}

思路2:使用回溯演算法,模板如下:

注:這題的陣列的長度沒有限制,因此每次遞迴的一開始可以直接把當前結果放入res。不需要等到數的葉子節點。如果像上面一題長度有限制,也就是必須到達葉子節點,那麼就不能這樣。

public list

> res;

public list

>

subsets

(int

nums)

res=

newarraylist

<

>()

;backtrack(0

,nums,

newarraylist

());

return res;

}private

void

backtrack

(int i,

int[

] nums, arraylist

tmp)

}

使用回溯演算法的示意圖:

列印乙個字串的全部子串行,包括空字串(abc的子串行包括a,ab,abc,bc,,,,)

思路1:使用樹的思想,每一位都可以選擇要或者不要,因為使用的是string,每次新增字元都會自動新生成乙個string物件,不是共用乙個物件,所以不需要每次使用完之後刪除。

思路2:使用上面的回溯模型,因為沒有規定相同的長度,所以不必等到葉子節點才返回。每一輪直接就可以返回。

輸入兩個數字 n, k,演算法輸出 [1…n] 中 k 個數字的所有組合。比如輸入 n = 4, k = 2,輸出如下結果,順序無所謂,但是不能包含重複(按照組合的定義,[1,2] 和 [2,1] 也算重複):leetcode77

使用回溯演算法的時候,示意圖如下:

public list

>

combine

(int n,

int k)

public

void

backtrack

(int n,

int index,

int k,list

> res,list

tmp)

}

這三類題目非常相似,但是又略有不同,只要記住了回溯的那個框架,其實都能寫出來,需要注意的是兩個問題:

第乙個:這個要求的子串行是不是長度固定的,如果不是,那麼在回溯裡面直接就可以加入結果集,而不需要等到長度一定(到達葉子節點)時才能返回結果。

第二個:如果其中暫存每種結果的集合是公用的,每次add之後必須remove。

最重要的還是腦海裡面有一張上面的二叉樹的那張圖,有了這個畫面就好寫了。

經典題型之回溯演算法 八皇后問題

include 判斷能不能在cnt行第col列擺放乙個皇后 能返回1 不能返回0 int judge int queens size t n,size t row,size t col return1 當前位置無威脅,返回1 輸出當前擺法的8個皇后的位置 void show int queens s...

環形鍊錶相關題型總結

leetcode 141 判斷鍊錶是否有環?leetcode 142 找到環形鍊錶的入口 求出環形鍊錶的長度 將環形鍊錶變成單鏈表 參考資料 第1題的關鍵在於利用快慢指標,若快指標能追上慢指標,則說明有環 第2題的關鍵在於當快慢指標第一次相遇時,再利用乙個新的entry指標指向head,讓其與慢指標...

暢通工程系列相關題型

上週花了一周多的時間看了最小生成樹,最短路,並查集這一塊內容,這是上週新學的知識點,時間拉的確實有點長,尤其是1875那一題卡了很久,用兩種方法寫比較混亂,雖然也是花了一周多的時間,但是也只會寫寫這些模板題,而且對於這些容易把 摻雜在一起寫,思路邏輯不清,這一點需要自己多去找找原因,理清思路。ac ...