題目:
分析:日常生活也會遇到的問題,數的思路是確定第一個數->考慮後面的所有組合情況,然後第一個數換一個->考慮後面的所有組合情況。接下來思考一個問題,是不是每個數都有機會做第一個數,答案是不一定,取決於每個組合中的個數是多少。
以題目示例爲例,組合中的個數是2,也就是說1-4裏面4是不可能當第一個數的,因爲它是末尾的數,後面沒有多的數了,而不可能與前面的數組合因爲這些組合之前已經考慮過了。
所以第一個位置可選的數受到總個數n和組合中的個數k限制。接着分析,既然是組合那麼不能有重複的數字出現,所以選定一個位置的數後,之後的位置不能再選這個數了,應該從這個數之後的數開始組合
思考到這,回溯的剪枝條件已經出來了
代碼:
class Solution {
public List<List<Integer>> combine(int n, int k) {
List<List<Integer>> result = new ArrayList<>();
List<Integer> path = new ArrayList<>();
back(n, k, result, path, 1);
return result;
}
static void back(int n, int k, List<List<Integer>> result, List<Integer> path, int begin){
if(k == 0){
result.add(new ArrayList<>(path));
return;
}
for(int i = begin; i <= n-k+1; i++){
path.add(i);
//k減少1個,i+1作爲下一個位置的數的起始選擇
back(n, k-1, result, path, i+1);
path.remove(path.size()-1);
}
}
}
代碼中爲什麼i<=n-k+1,因爲上面說過,能做第一個位置的數和接下來能選的數是有限制的同時受到總個數n和組合中的個數k限制,以第一個位置爲例,最後一個能當第一個位置的數的位置i,必有如下關係:i+(k-1)=n,所以i=n-k+1(這裏的k指組合中的個數限制,n指末尾位置,題目剛好1-n數值等於位置)