給定乙個無重複元素的陣列 candidates 和乙個目標數 target ,找出 candidates 中所有可以使數字和為 target 的組合。
candidates 中的數字可以無限制重複被選取。
說明:所有數字(包括 target)都是正整數。
解集不能包含重複的組合。
示例 1:
輸入:candidates = [2,3,6,7], target = 7,
所求解集為:
[[7],
[2,2,3]
]
簡單的回溯基本就是回溯的模板,注意點就是返回的arraylist不能作為引數放進方法中,因為每次回溯都會回到之前的狀態。
直接上**
class
solution
public
void
backstrace
(int
candidates,
int target,arraylist
temp,
int p)
if(target<0)
return
;for
(int i=p;i}
給定乙個陣列 candidates 和乙個目標數 target ,找出 candidates 中所有可以使數字和為 target 的組合。
candidates 中的每個數字在每個組合中只能使用一次。
說明:所有數字(包括目標數)都是正整數。
解集不能包含重複的組合。
示例 1:
輸入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集為:
[[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]
思路使用set天然的除重,但是**結構會比較複雜剪枝
注意到題目裡說的是「每個數字在每個組合使用一次」,意味著數值相同但不是同乙個的數字,可以在同乙個組合**現。即可以有[1,1,6]這種情況。不重複就需要按順序搜尋,在搜尋的過程中檢測分支是否會出現重複結果。注意:這裡的順序不僅僅指數組candidates
有序,還指按照一定順序搜尋結果。
class
solution
public
void
backstrace
(int
candidates,
int target,arraylist
temp,
int p)
if(target<0)
return
;for
(int i=p;i}
總體的**和上一題差不多,關鍵是在剪枝的位置
if
(i>p&&candidates[i]
==candidates[i-1]
)continue
;
為什麼這麼寫可以刪除重複的。這裡借用leetcode上看到的解釋
這個避免重複當思想是在是太重要了。
這個方法最重要的作用是,可以讓同一層級,不出現相同的元素。即
1/ \
2 2 這種情況不會發生 但是卻允許了不同層級之間的重複即:
/ \
5 5例21
/2 這種情況確是允許的
/2
為何會有這種神奇的效果呢?
首先 cur-1 == cur 是用於判定當前元素是否和之前元素相同的語句。這個語句就能砍掉例1。
可是問題來了,如果把所有當前與之前乙個元素相同的都砍掉,那麼例二的情況也會消失。
因為當第二個2出現的時候,他就和前乙個2相同了。
那麼如何保留例2呢?
那麼就用cur > begin 來避免這種情況,你發現例1中的兩個2是處在同乙個層級上的,
例2的兩個2是處在不同層級上的。
在乙個for迴圈中,所有被遍歷到的數都是屬於乙個層級的。我們要讓乙個層級中,
必須出現且只出現乙個2,那麼就放過第乙個出現重複的2,但不放過後面出現的2。
第乙個出現的2的特點就是 cur == begin. 第二個出現的2 特點是cur > begin.
給定乙個 沒有重複 數字的序列,返回其所有可能的全排列。
示例:輸入: [1,2,3]
輸出:[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
思路基本的回溯,用乙個標誌陣列用來除重。
class
solution
public
void
backstrace
(list
> res,arraylist
temp,
int nums,
boolean label)
for(
int i=
0;i}}
給定乙個可包含重複數字的序列 nums ,按任意順序 返回所有不重複的全排列。
示例 1:
輸入:nums = [1,1,2]
輸出:[[1,1,2],
[1,2,1],
[2,1,1]]
思路與上一題不同的地方在於給的陣列中有重複元素,
用set去重,只需增加一步用set去重
class
solution
}
2.剪枝,思想與40一樣,允許下乙個,不允許自身
class
solution
public
void
backstrace
(list
> res,arraylist
temp,
int nums,
boolean label)
for(
int i=
0;i}
注意這裡的
if
(i>
0&&label[i-1]
==false
&&nums[i]
==nums[i-1]
)continue
label[i-1]==false的作用為判斷是否在同一層,若在同一層則去除,為下一層則保留。 很多問題1
1054 猴子吃桃 1056 幸運數字 1059 最高分 時間限制 1 sec 記憶體限制 128 mb 輸入x,計算上面公式的前10項和。輸入乙個實數x。輸出乙個實數,即數列的前10項和,結果保留3位小數。0.841 include include include intmain printf 3...
leetcode 子集問題(回溯演算法)
給你乙個整數陣列 nums 陣列中的元素 互不相同 返回該陣列所有可能的子集 冪集 解集不能包含重複的子集。你可以按 任意順序 返回解集。示例 1 輸入 nums 1,2,3 輸出 1 2 1,2 3 1,3 2,3 1,2,3 示例 2 輸入 nums 0 輸出 0 解決子集問題最常用的方法就是回...
leetcode 遞迴 回溯問題 總結
注意 整體思路清晰,回溯的過程大概是怎樣的 每層遞迴實際上要解決的問題是什麼 一定記住,該重置的狀態要重置,因為回溯就是相當於在每一層的遞迴中做選擇,選擇了不同的選項,在遇到阻礙或者達到條件結束遞迴之後,再想嘗試其他的選擇路徑,應當記住回退到之前的狀態。縱向 遞迴的深度,完整地解決問題 搜尋完所有的...