一緒に書く習慣を身につけましょう!「ナゲッツデイリーニュープラン・4月アップデートチャレンジ」に参加して26日目です。クリックしてイベントの詳細をご覧ください。
1.問題の説明
合計して次の条件を満たす数値のすべての 組み合わせn
を 見つけます。k
- 1から9までの数字のみを使用してください
- 各番号 を最大で1回使用する
可能なすべての有効な組み合わせのリストを返します 。リストに同じ組み合わせを2回含めることはできません。組み合わせは、任意の順序で返すことができます。
トピックリンク:Combined Sum III
第二に、主題の要件
サンプル
输入: k = 3, n = 7
输出: [[1,2,4]]
解释:
1 + 2 + 4 = 7
没有其他符合的组合了。
复制代码
訪問
1.回溯算法
2.建议用时20~35min
复制代码
3.問題分析
この質問は3
、バックトラッキングアルゴリズムを開いて質問をブラッシングする最初の質問です。これまでに理解したことがない場合は、この質問の解決策を見て、より詳細に説明することができます。
アルゴリズムは毎日の練習に質問します---85日目:組み合わせ
この質問は、前にブラッシングしたアルゴリズムの質問を使用した日常の練習です--- 88日目:組み合わせ合計IIは非常に似ているか、より単純です。この質問では1〜9しか使用できず、繰り返し要素がないためです。 、重い剪定操作を実行する必要はありません。
最初の式:関数初期
バックトラッキングを実行するために関数を初期化したいのですが、関数のパラメーターを決定するにはどうすればよいですか?
まず、指定された配列情報、ターゲット値、および初期トラバーサルのインデックスを渡す必要があります。
vector<int>t;
vector<vector<int>>v;
void DFS(int begin,int target,int k)//函数初始
复制代码
タイプ2:終了条件
条件を終了して下に進み、検索を開始するのはいつですか?
タイトルには、ターゲットが構成できる配列の要素が必要です。追加された要素ごとに、ターゲットはこの要素の値を減算する必要があります。
target == 0で、この時点での配列要素の数がkに等しい場合、終了条件が満たされます。
if(target==0&&t.size()==k)//终止条件
{
v.push_back(t);
return;
}
复制代码
3番目の式:剪定の最適化
この質問の剪定は比較的簡単であり、上記の終了条件は0に等しくありません。
次に、ターゲットがすでに0未満で、配列の数がkより大きい場合でも、検索を続行する必要がありますか?完全に不要です。
if(target<0||t.size()>k)//剪枝优化
return;
复制代码
4番目のタイプ:再帰処理
for(int i=begin;i<=9;i++)//递归处理
{
if(i<=target)
{
t.push_back(i);//添加数据
DFS(i+1,target-i,k);
t.pop_back();//回溯
}
}
复制代码
iがターゲットよりも小さい場合は、毎回配列に追加し、ターゲット値からiの値を減算します。
テンプレート:
void DFS(变量)//函数初始
{
if(条件1||条件2...)//终止条件
{
v.push_back(t);
return;
}
if (条件1||条件2...)//剪枝
return;
for(int i=cur;i<=n;i++)//递归处理
{
//选择当前数字
DFS(向下遍历);
//回退
}
}
复制代码
あふれる想い!
第四に、エンコーディングの実装
class Solution {
public:
vector<int>t;
vector<vector<int>>v;
void DFS(int begin,int target,int k)//函数初始
{
if(target==0&&t.size()==k)//终止条件
{
v.push_back(t);
return;
}
if(target<0||t.size()>k)//剪枝优化
return;
for(int i=begin;i<=9;i++)//递归处理
{
if(i<=target)
{
t.push_back(i);
DFS(i+1,target-i,k);
t.pop_back();
}
}
}
vector<vector<int>> combinationSum3(int k, int n) {
DFS(1,n,k);//调用回溯函数
return v;
}
};
复制代码