2016.7.22
groupSum
Given an array of ints, is it possible to choose a group of some of the ints, such that the group sums to the given target? This is a classic backtracking recursion problem. Once you understand the recursive backtracking strategy in this problem, you can use the same pattern for many problems to search a space of choices. Rather than looking at the whole array, our convention is to consider the part of the array starting at index start and continuing to the end of the array. The caller can specify the whole array simply by passing start as 0. No loops are needed -- the recursive calls progress down the array.
groupSum(0, [2, 4, 8], 10) → true
groupSum(0, [2, 4, 8], 14) → true
groupSum(0, [2, 4, 8], 9) → false
public boolean groupSum(int start,int[] nums,int target){ }
題意:
給定一個(gè)int型數(shù)組,你可以選擇數(shù)組的中的數(shù)相加來(lái)得到給定的目標(biāo)數(shù)嗎?這是一個(gè)經(jīng)典的回溯遞歸問(wèn)題。一旦你在這個(gè)問(wèn)題上了解了遞歸回溯策略,你可以使用相同的模式為許多問(wèn)題提供一個(gè)搜尋空間的解決方法。我們的慣例是考慮從索引開(kāi)始到結(jié)束的數(shù)組部分,而不是看整個(gè)數(shù)組。調(diào)用方可以簡(jiǎn)單地通過(guò)從0開(kāi)始指定整個(gè)數(shù)組。沒(méi)有循環(huán)是必要的-遞歸調(diào)用的數(shù)組的進(jìn)度。
即,從start索引開(kāi)始從數(shù)組nums中選擇若干個(gè)數(shù)來(lái)相加得到一個(gè)target的值,能則返回true,不能則返回false。
整個(gè)問(wèn)題的關(guān)鍵:怎么返回分支口并進(jìn)入另一個(gè)分支
思路:
groupSum方法的返回類型是boolean類型,我們可以先加上索引對(duì)應(yīng)的數(shù)組數(shù),然后用groupSum將剩下的對(duì)應(yīng)參數(shù)傳入,并作為if的表達(dá)式,這樣它返回的就是加過(guò)這個(gè)數(shù)后還能否得到剩下的target。
如果能則返回true;不能則不加這個(gè)數(shù),并將索引加1后傳入groupSum。
在方法的最前面寫(xiě)判斷遞歸結(jié)束的條件和結(jié)果。
public boolean groupSum(int start,int[] nums,int target){
if(target==0)
return true;
if(start==nums.length)
return false;
if(groupSum(start+1,nums,target-nums[start])){
return true;
}
else{
return groupSum(start+1,nums,target);
}
}
可能看懂了代碼的意思,但還不是很理解它到底是怎么遞歸怎么回溯的。
下面我做了一個(gè)圖,幫助大家看懂
圖片很大,但顯示問(wèn)題網(wǎng)頁(yè)上放不了多大,建議下載遞歸回溯groupSum下來(lái)看
思路更清晰的代碼(2016.7.30補(bǔ))
public boolean groupSum(int start,int[] nums,int target){
if(target==0)
return true;
if(start==nums.length)
return false;
return groupSum(start+1,nums,target-nums[start])||groupSum(start+1,nums,target);
}