1. 程式人生 > >leetcode39組合總和

leetcode39組合總和

class Solution {
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        vector<vector<int> > ans;
        vector<int> tmp;
        if (candidates.empty()) {
            return ans;
        }
        helper(candidates, target, 0, ans, tmp);
        return ans;
       
    }
private:
     void helper(vector<int>& candidates, int target, int start, vector<vector<int> > &ans, vector<int> &tmp) {
            if (target < 0) {
                return;
            }
            if (target == 0) {
                ans.push_back(tmp);
            }
            // 這裡的start的值賦值個i, 決定了開始位置,也就是說,假設start==1, 那麼只能取candidate[1]以及以後的數字
            //   start = 0
            //    i 的取值範圍 :  [0,1,2,3,4,5]
            //   start = 1
            //    i 的取值範圍 :  [1,2,3,4,5]
            //   start = 2
            //    i 的取值範圍 :  [2,3,4,5]
            //   start = 3
            //    i 的取值範圍 :  [3,4,5]
            //    就這樣依次走下去
            // 這就有點相當於  for start == 0 to n:
            //                      for  i == start to n:
            //                           for  j ==  i to n : (下面的註釋解釋了這一行虛擬碼)
            for (int i = start; i < candidates.size(); i++) {
                tmp.push_back(candidates[i]);
                // 最重要的一點在這個i上, 這關係到資料是如何被選取的,要考慮為什麼不是start, 也不是start+1,也不是i+1
                // start               假設start==0的時候  i的取值範圍是[1,2,3,4,5]
                // |   i               現在i移動到了3 那麼下一步要怎麼進行呢? 題目要求,此時後面的數字的取值範圍就是[3,5],                 // |   |                 因為可重複,所以能取到3, 最大的值呢就是5, 所以這裡就只能取i
                // 1 2 3 4 5 
                helper(candidates, target - candidates[i], i , ans, tmp);
                tmp.pop_back();
            }
        }
};