2023-01-09Day24第七章回溯算法

回溯算法可以用于解決:
組合問題:N個(gè)數(shù)里面按一定規(guī)則找出k個(gè)數(shù)的集合
切割問題:一個(gè)字符串按一定規(guī)則有幾種切割方式
子集問題:一個(gè)N個(gè)數(shù)的集合里有多少符合條件的子集
排列問題:N個(gè)數(shù)按一定規(guī)則全排列,有幾種排列方式
棋盤問題:N皇后,解數(shù)獨(dú)等等

回溯算法三部曲:
1.回溯函數(shù)模板返回值以及參數(shù)
2.回溯函數(shù)終止條件
3.回溯搜索的遍歷過程

算法框架

void backtracking(參數(shù)) {
    if (終止條件) {
        存放結(jié)果;
        return;
    }

    for (選擇:本層集合中元素(樹中節(jié)點(diǎn)孩子的數(shù)量就是集合的大?。? {
        處理節(jié)點(diǎn);
        backtracking(路徑,選擇列表); // 遞歸
        回溯,撤銷處理結(jié)果
    }
}

for 橫向遍歷(i=1,2,..,),遞歸縱向遍歷
組合問題
77. 組合 - 力扣(Leetcode)

給定兩個(gè)整數(shù) n 和 k,返回范圍 [1, n] 中所有可能的 k 個(gè)數(shù)的組合。
你可以按 任何順序 返回答案。

class Solution:
    def combine(self, n: int, k: int) -> List[List[int]]:
        res = []
        path = []
        def backtracking(n,k,startindex):
            if len(path) ==k:
                res.append(path[:])
                return
            # 剪枝, 最后k - len(path)個(gè)節(jié)點(diǎn)直接構(gòu)造結(jié)果,無(wú)需遞歸
            last_index = n-(k-len(path))+1 
            for i in range(startindex,last_index+1):
                path.append(i)
                backtracking(n,k,i+1) #遞歸
                path.pop() #回溯
        backtracking(n,k,1)
        return res 

對(duì)于last_index 處理節(jié)點(diǎn)上界的理解:
比如n=15,k=4,len(path)=1時(shí),接下來(lái)要選3個(gè)數(shù),遍歷的起點(diǎn)最大是13,最后一個(gè)被選的是[13,14,15],在這個(gè)時(shí)候14和15開頭的長(zhǎng)度不夠,肯定不符合,就不需要處理可以進(jìn)行剪枝。
比如n=5,k=3,len(path)=0,需要再選3個(gè)數(shù),遍歷起點(diǎn)最大的數(shù)是3,最后一個(gè)被遍歷的列表是[3,4,5],對(duì)于這個(gè)時(shí)候4和5開頭的就不需要處理了,就是剪枝。
所有可以歸納:
處理節(jié)點(diǎn)上界=n-(k-len(path))+1
所以last_index=n-(k-len(path))+1
而last_index+1則是因?yàn)閞ange區(qū)間左閉右開
這個(gè)問題中n相當(dāng)于樹的寬度,k相當(dāng)于樹的深度。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容