回溯法
回溯法往往用來找出乙個問題的所有可能解(而不是簡單的回答出有多少個解,如果是問解的個數,可能有更好的辦法,也就是動態規劃)。
回溯法是dfs的一種,但又和dfs不一樣,dfs往往求解連通面積,可達性的問題,而回溯法往往求解滿足某一條件的所有組合,比如二叉樹的路徑和,排列組合等經典問題。
回溯法在**層面,最明顯的特徵就是
終止條件的判斷
如果當前組合滿足條件,加入結果集
開始遍歷元素
把某一元素加入組合
遞迴呼叫
再把該元素剔除組合
以 257. 二叉樹所有路徑 為例,進行簡單的解釋:
/**
* definition for a binary tree node.
* public class treenode
* }*/class
solution
list
res =
newarraylist
();backtracking
(root,
newarraylist
(),res)
;return res;
}private
void
backtracking
(treenode node, list
list,list
res)
else
//6,再把該元素剔除組合
list.
remove
(list.
size()
-1);
}private string buildpath
(list
list)
return sb.
tostring()
;}}
其實這些是最基本的,如果想要達到回溯法的高階要求,還得往下看。
其實回溯法最經典的應用當屬排列組合,這是兩個問題,往往有以下幾種形式:
排列+無重複元素
排列+有重複元素
組合+無重複元素
組合+有重複元素
區別在**呢?
排列與組合的區別
排列要考慮元素的順序,順序不一樣,是不一樣的組合,需要引入boolean陣列進行標識,是否已經在當前的組合裡了。
組合不需要考慮順序。
有重複元素和無重複元素
如果有重複元素,往往需要排序+利用boolean陣列去重,因此經常會用到這一段**:
for
(int i =
0;i)
無重複元素,也要注意,元素個數是否可以無限制。
問題雜記:
list
> res =
newarraylist
<
>()
;
if
(list.
size()
== nums.length)
也就是遍歷的時候不是從0開始,這個要看情況使用,往往用於組合+無重複元素
//不是從0開始
for(
int i = startindex;i)
什麼情況下需要它呢?
1 有重複元素時(主要還是用來去重)
2 無重複元素+排列(標記該元素是否使用過)
leetcode刷題總結之回溯法
前言 最近太懶了,好久都沒寫總結了。回溯法是看labuladong的詳解回溯法入的門,然後看了 計算機演算法設計與分析 第5章的回溯法部分弄清了原理,在leetcode上做了差不多20個題,今日總結一下,供以後複習用。回溯法的定義 回溯法有通用解法的美稱,對於很多問題,如迷宮等都有很好的效果。回溯法...
演算法思想 回溯法
很多經典的數學問題都可以用回溯演算法解決,比如數獨 八皇后 0 1 揹包 圖的著色 旅行商問題 全排列等等。籠統地講,回溯演算法很多時候都應用在 搜尋 這類問題上。不過這裡說的搜尋,並不是狹義的指我們前面講過的圖的搜尋演算法,而是在一組可能的解中,搜尋滿足期望的解。回溯演算法的理論知識很容易弄懂。不...
LeetCode刷題(八) 二叉搜尋樹 回溯法
二叉搜尋樹定義 1.validate binary search tree 判斷給出的二叉樹是否是乙個二叉搜尋樹 bst class solution bool isvalidbst treenode root if tag false return true else return false e...