タイトル
負でない整数の配列、A1、A2、...、と、目標の数、S.考えます - 今、あなたは二つのシンボル+としています。任意の整数配列の場合、あなたは+またはからすることができます - 前に追加したシンボルを選択します。
そして、シンボルの数を追加するためのすべての方法を返すことができ、最終的な配列はS.の目標数であります
例1:
入力:NUMS:[1、1、 1、1、1]、S:3
出力:5
説明:
-1 + 1 + 1 + 1 + 1 = 3
+ 1-1 + 1 + 1 + 1 = 3
+ 1 + 1-1 + 1 + 1 = 3
+ 1 + 1 + 1-1 + 1 = 3
+1 + 1 + 1 + 1-1 = 3
究極の目標と3を作るための5つの方法があります。
注意:
非空の配列、及び20以下の長さ。
最初の配列ではなく、1,000以上。
最終結果は32ビット整数を保存することができる戻すことができます。
出典:ボタン(LeetCode)滞在
:リンクhttps://leetcode-cn.com/problems/target-sum
すべてのネットワークからの控除が著作権を保有します。商業転載は許可公式、非商用の転載は、ソースを明記してくださいお問い合わせください。
問題の解決策
問題は、2つのデジタルコレクション(サブセットと私は設定)に分けることができます。
私は和= Sセットsum-のサブセット(有)
(同時に+ Iの電流和サブセット和の両側を添加)サブセット和+ I現在の和+サブセットsum- I和集合=サブセット和+ I現在の和+ S
(すなわち)2 *合計はセットS + SUMのサブセット=
/ 2(すなわち)サブセット和=(集合和+ S)
になるように問題をQiuziセットとどのように多くの固定値の組合せ。各数値は、選択したかどうか選択することができ、0-1ナップザック問題解決のために使用することができます。
NUMを横断したときに、DP [j]はだけ前とNUM NUMを横断表し、jは種の組み合わせの数です。、クラシック0-1ナップザック問題は、0-1ナップザック問題を理解し、状況よりも一次元アレイとすることができます。
他の
TODOはまた、DFSで解決することができます。
コード
class Solution {
public int findTargetSumWays(int[] nums, int S) {
int setSum=0;
for(int num:nums) {
setSum+=num;
}
if((setSum+S)%2==1) {
return 0;
}
int subSetSum=(setSum+S)/2;
int[] dp=new int[subSetSum+1];
dp[0]=1;
for(int num:nums) {
for(int j=subSetSum;j>=num;--j) {
dp[j]+=dp[j-num];
}
}
return dp[subSetSum];
}
}