import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param weights int整型一维数组
* @return bool布尔型
*/
public boolean canPartition (int[] weights) {
// write code here
int sum = Arrays.stream(weights).sum();
if ((sum & 1) == 1) return false;
sum >>= 1;
boolean[] f = new boolean[sum + 1];
f[0] = true;
for (int x : weights) {
for (int j = sum; j >= x; j--) {
f[j] = (f[j] || f[j - x]);
}
}
return f[sum];
}
}
修改后的代码使用的编程语言是Java。
该题考察的知识点包括:
- 动态规划:代码中使用了动态规划的思想来解决背包问题,通过填表格的方式求解能否将一组物品分成两个相等的子集。
- 数组操作:使用数组来记录状态转移和计算是否能够平分重量。
代码的解释:
- 使用
Arrays.stream(weights).sum();计算整数数组weights中所有元素的总和。 - 判断总和的奇偶性:如果总和是奇数,则无法分成两个相等的子集,直接返回
false。 - 计算目标和:将总和除以 2,得到目标和,因为要找到能够达到目标和的子集。
- 创建状态数组:使用
boolean[] f来表示是否可以通过选择一些元素得到特定的重量和。数组长度为sum + 1,因为重量和的范围是从 0 到目标和。 - 初始化状态:将
f[0]设为true,表示总和为 0 的情况下可以选择不取任何元素。 - 动态规划状态转移:遍历
weights数组中的每个元素x,然后从目标和开始往前遍历,更新f[j]为f[j] || f[j - x],表示在选择或不选择当前元素x的情况下,能否得到重量和为j。 - 返回结果:返回
f[sum],表示是否能够通过选择一些元素得到目标和,从而将数组分成两个相等的子集。

京公网安备 11010502036488号