Mdfs lc39 組合總和 dfs 經典

2021-10-12 17:45:57 字數 2275 閱讀 4412

必看,必刷,dfs 經典:

需要統計所有的方案數,那麼完全揹包在這貌似就不能使用了。就暴力搜所有方案就行了。

暴搜順序是很重要的,在這順序遍歷陣列中的每乙個數,並列舉它可能取的所有個數,就能不重不漏的搜完所有可能方案。

**細節:

dfs暴搜,一直都被認為是簡單,確實,但是還是得多寫點題,才能考慮到搜尋順序和**邊界、細節情況!

看看官方題解蠻不錯的,**很清楚!

時間複雜度:不會分析…

空間複雜度:不會分析…,這個貌似是 o(t

arge

t)

o(target)

o(targ

et)?就是遞迴深度吧

**:

class

solution

void

dfs(vector<

int>

& c,

int u,

int target)

// 如果列舉完最後乙個數還沒能湊出target,則直接 return

if(u == c.

size()

)return

;// u表示列舉到當前的數

// c[u] * i <= target 選i個,最小單位為1,相乘則表示不能超過target這個值

for(

int i =

0; c[u]

* i <= target;

++i)

// 恢復現場

for(

int i =

0; c[u]

* i <= target;

++i)}}

;

2023年08月24日 個人理解:

這個 dfs 走了個頓挫,就很巧妙。因為一開始c[u]的選取個數i是從 0 開始的。所以在進入下一層時,要保證path中沒有c[u]存在,所以先讓它進入下一層,然後再給path中新增乙個c[u]進去。

這樣就能保證每次進入下一層時,path中的c[u]個數和i的值保持一致。即和定義相同。

並且如果c[u]乙個都不能選的話,必然在i=1時跳出for迴圈,這個尾部加如的 1 個c[u]就會立馬被恢復現場清掉,並不會產生錯誤的影響,很是巧妙。

class

solution

// 選當前數。i從0 開始,指的是不選當前數的情況

for(

int i =

0; c[u]

* i <= target; i ++

)/* 當i=1時,path 中才會有乙個c[u]存在,並dfs到下一層,而當 i=0時,path中並沒有存在的該元素,就直接dfs到下一層。

由於i=0是必然要執行一次的,因為c[u]*0<=target 必然成立。

但是,如果緊接著 i=1不成立的話,for 迴圈跳出,這個剛加進去的c[u]就會被立馬pop_back掉。並不影響答案

所以這個寫法就保證了,在dfs過程中i與path中c[u]的個數的嚴格對應。

即,一開始,for迴圈進入,是 0 個,dfs進入下一層也是0個,然後回到本層時,才在尾部立馬加 1 個,緊接著 i=1 就進入下一層dfs

此時,path中就有了剛剛那個剛加入的1個c[u]。

所以用這種方式,將 i個c[u]與列舉的層數嚴格對應起來。保證在進入下一層時,當前的c[u]是i個。

即i=0時,進入下一層時,c[u]是0個

i=1時,進入下一層時,c[u]是1個

...仍要多多理解

*/for(

int i =

0; c[u]

* i <= target; i ++

) path.

pop_back()

;}vectorint>>

combinationsum

(vector<

int>

& c,

int target)

};

LeetCode 39 組合總和 DFS

給定乙個無重複元素的陣列 candidates 和乙個目標數 target 找出 candidates 中所有可以使數字和為 target 的組合。candidates 中的數字可以無限制重複被選取。說明 所有數字 包括 target 都是正整數。解集不能包含重複的組合。示例 1 輸入 candid...

力扣 39 組合總和 dfs

不同組合,並以列表形式返回。你可以按任意順序返回這些組合。candidates中的同乙個數字可以無限制重複被選取。如果至少乙個數字的被選數量不同,則兩種組合是不同的。對於給定的輸入,保證和為target的不同組合數少於150個。示例 1 輸入 candidates 2,3,6,7 target 7 ...

39 組合總和

給定乙個無重複元素的陣列 candidates 和乙個目標數 target 找出 candidates 中所有可以使數字和為 target 的組合。candidates 中的數字可以無限制重複被選取。說明 示例 1 輸入 candidates 2,3,6,7 target 7,所求解集為 7 2,2...