216 組合總和 III(遞迴)

2021-10-24 06:18:39 字數 2800 閱讀 7027

1. 問題描述:

找出所有相加之和為 n 的 k 個數的組合。組合中只允許含有 1 - 9 的正整數,並且每種組合中不存在重複的數字。

說明:所有數字都是正整數。

解集不能包含重複的組合。 

示例 1:

輸入: k = 3, n = 7

輸出: [[1,2,4]]

示例 2:

輸入: k = 3, n = 9

輸出: [[1,2,6], [1,3,5], [2,3,4]]

2. 思路分析:

① 分析題目可以知道題目的規模大概是確定的,組合的數字是1~9而且是不允許重複的,我們需要嘗試出所有的可能性才可以找到所有相加之和為 n 的 k 個數的組合,很明顯這個問題是可以使用遞迴來解決的,遞迴就是在不知道的情況下去搜尋問題的所有方案,在搜尋的過程中找到滿足題目條件的結果,所以對於這道題目來是可以使用遞迴來進行解決的。

② 這個是1-9而且是不允許重複的數字組合,有點類似於填寫數獨上的數字的問題,只是處理的細節不一樣而已,對於這道題目來說,也是需要在for迴圈中進行遞迴(類似於數獨),比如k = 3, n = 9,當我們嘗試出第乙個結果[1,2,6],發現往下遞迴的過程中都是不滿足n = 9的,最後將會退回到第二層也就是退回到數字2的情況,這個時候我們需要嘗試數字3-9的情況,也就是嘗試當前這一層的平行狀態,所以會得到[1,3,5]這個結果,所以這個是需要在for迴圈中進行遞迴求解的,結合數獨的問題會更好理解。

③ 由②可知我們需要在for迴圈中進行遞迴,所以我們只需要在方法中傳入需要的各個引數即可,記錄當前使用數字的數目,記錄當前數字的累加和,記錄中間結果的乙個列表,當前正在遞迴的數字是哪乙個,這樣下一次遞迴的時候肯定大於當前這個數字的,也即規定選擇數字的順序這樣就可以筆墨安重複組合的問題。

記錄中間結果的列表:我們需要往下遞迴之前進行剪枝,判斷遞迴下去是否有意義,假如有意義那麼需要在遞迴之前將當前的使用的數字記錄下來,最後我們需要在出口中判斷出當前使用的數字與累加的和是否等於題目中要求的k與n的值,假如相等那麼加入到結果集中,並且需要return。

④ 因為是1~9這個數字而且要求是不重複的,所以資料的規模並不是特別大,使用遞迴是可以求解出來的。

3. **如下:

from typing import list

class solution:

""":param count:當前使用了多少個數字

:param cur: 當前使用的數字的累加和

:param num: 當前使用的數字, 往下遞迴的時候傳入當前數字的下乙個數字

:param res: 最後需要返回的結果列表

:param rec: 記錄使用的數字中間結果

:return:

"""def dfs(self, k: int, n: int, count: int, cur: int, num: int, res: list[list[int]], rec: list[int]):

if count == k and cur == n:

# 通過切片操作將記錄的結果加入到結果列表中, 使用python的切片操作可以實現拷貝整個列表的副本

new = rec[:]

# 退回到上一層

return

for i in range(num, 10):

# 剪枝: 只有當前使用的數字小於了k並且累加和使小於等於n的才進行遞迴

if count < k and cur + i <= n:

# 新增當前的數字

# i + 1表示遞迴當前數字的下乙個數字這樣可以避免重複

self.dfs(k, n, count + 1, cur + i, i + 1, res, rec)

rec.pop()

def combinationsum3(self, k: int, n: int) -> list[list[int]]:

res, rec = list(), list()

# 使用dfs搜尋即可

self.dfs(k, n, 0, 0, 1, res, rec)

return res

from typing import list

class solution:

# start表示開始的數字, n表示還剩餘多少總和, res用來記錄答案, rec用來記錄中間結果

# n與k在遞迴過程中都是減少的這樣當等於0的時候表示剛好湊好了

def dfs(self, start: int, n: int, k: int, res: list[list[int]], rec: list[int]):

if n == 0:

if k == 0:

elif k != 0:

for i in range(start, 10):

# 只有當n大於等於i才可以繼續遞迴下去, 這樣所有數字的累加的和才小於等於n的

# 這樣就可以去除重複方案

if n >= i:

# 往下遞迴的時候開始的數字都是加1的這樣可以避免重複

self.dfs(i + 1, n - i, k - 1, res, rec)

rec.pop()

def combinationsum3(self, k: int, n: int) -> list[list[int]]:

res = list()

rec = list()

self.dfs(1, n, k, res, rec)

return res

216 組合總和 III

題目 找出所有相加之和為 n 的 k 個數的組合。組合中只允許含有 1 9 的正整數,並且每種組合中不存在重複的數字。說明 所有數字都是正整數。解集不能包含重複的組合。示例 1 輸入 k 3,n 7 輸出 1,2,4 示例 2 輸入 k 3,n 9 輸出 1,2,6 1,3,5 2,3,4 分析 d...

leetcode 216 組合總和 III

找出所有相加之和為 n 的 k 個數的組合。組合中只允許含有 1 9 的正整數,並且每種組合中不存在重複的數字。說明 示例 1 輸入 k 3,n 7 輸出 1,2,4 示例 2 輸入 k 3,n 9 輸出 1,2,6 1,3,5 2,3,4 class solution 因為只能用1 9的數字,且每...

LeetCode 216 組合總和 III

官方鏈結 找出所有相加之和為 n 的 k 個數的組合。組合中只允許含有 1 9 的正整數,並且每種組合中不存在重複的數字。說明 所有數字都是正整數。解集不能包含重複的組合。示例 1 輸入 k 3,n 7 輸出 1,2,4 示例 2 輸入 k 3,n 9 輸出 1,2,6 1,3,5 2,3,4 方案...