416.等しいサブセットとサブセットの分割
トピックリンク
出典:LeetCode
リンク:https://leetcode-cn.com/problems/partition-equal-subset-sum
著作権はLeetCodeが所有しています。商用転載の場合は、公認機関にご連絡ください。非商用転載の場合は、出典を明記してください。
タイトル説明
正の整数のみを含む空でない配列が与えられます。この配列を2つのサブセットに分割して、2つのサブセットの要素の合計が等しくなるようにすることは可能ですか。
注意:
各配列の要素は100を超えません。配列
のサイズは200を超えません。
例1:
入力:[1、5、11、5]
出力:true
説明:アレイは[1、5、5]と[11]に分割できます。
例2:
入力:[1、2、3、5]
出力:false
説明:配列を2つのエレメントと等しいサブセットに分割することはできません。
トピック分析
1次元配列
dpの初期値はデフォルトでfalseです。
dp [j]は、numsの[0、i]添え字が複数の整数を選択するかどうかを示し、整数の合計をjにするスキームがあるかどうかを示します。
dp [j] = dp [j-nums [i]] || dp [j]; 1次元配列が使用されているため、現在のdp [j]はdp [j-nums [i]]であり、前のステップ[j] OR演算を実行します。つまり、真の場合は真です。このステップに注意してください。
結果が正しくない場合は、配列を2回印刷して、正しい配列で観察することができます。値に違いがある場合は、ロジックが間違っています。
class Solution {
public boolean canPartition(int[] nums) {
boolean dp[] = new boolean[20001];
int sum =0;
int maxNum = nums[0];
for(int num:nums){
sum+=num;
maxNum = maxNum>num?maxNum:num;
}
if(sum%2!=0){
return false;
}
int target = sum/2;
if(maxNum>target){
return false;
}
for(int i=0;i<nums.length;i++){
for(int j = target;j>=nums[i];j--){
//要从后往前 不可颠倒
if(j==nums[i]){
dp[j] = true;
}else{
dp[j] = dp[j-nums[i]] || dp[j];
}
}
}
return dp[target];
}
}