[バックトラッキング] [leetcode]とターゲット番号の組み合わせ(番号は再利用可能)

トピック:

重複する要素のない配列候補とターゲット数のターゲットが与えられた場合、数の合計をターゲットにすることができる候補のすべての組み合わせを見つけます。

候補者の数は、制限なく繰り返し選択できます。

説明:

  • すべての数値(ターゲットを含む)は正の整数です。
  • ソリューションセットに繰り返しの組み合わせを含めることはできません。 

促す:

  • 1 <=候補者。長さ<= 30
  • 1 <=候補者[i] <= 200
  • 候補の各要素は一意です。
  • 1 <=ターゲット<= 500

例:

入力:候補= [2,3,6,7]、ターゲット= 7、
解集合は次のとおりです:
[
  [7]、
  [2,2,3]
]

ソース:

39.組み合わせ合計

問題解決のアイデア:バックトラック

バックトラックのアイデアを学び続けます。前の2つの組み合わせとの違いは、この質問が1)配列が並べ替えられていないため、最初に並べ替えられていることです。2)数値を再利用できるため、パラメーターが+ではなくなっていることです。再帰中に1。

  • 再帰的終了条件:現在の合計がターゲット以上
  • 結果は次の条件を満たしています:sum == target
  • 剪定条件:現在の合計が目標値を超えようとしています

c ++コード:

class Solution {
public:
    vector< vector<int> > result;
    vector<int> path;
    vector< vector<int> > combinationSum(vector<int>& candidates, int target) {
        sort(candidates.begin(), candidates.end()); // 排序
        back(candidates, target, 0, 0);
        return result;
    }
    void back(const vector<int>& candidates, int target, int sum, int start) {
        if (sum == target) {
            result.push_back(path);
            return;
        }

        for (int i = start; i < candidates.size(); i++) {
            if (sum + candidates[i] > target) break; // 剪枝
            path.push_back(candidates[i]);
            sum += candidates[i];
            back(candidates, target, sum, i); // 因为可以重复使用数字,所以i而不是i+1
            sum -= candidates[i];
            path.pop_back();
        }
    }
};

 

おすすめ

転載: blog.csdn.net/hbuxiaoshe/article/details/114836617