leetcode416
class Solution {
public boolean canPartition(int[] nums) {
int sum=0;
for (int num:nums) sum+= num;
if(sum % 2 == 1) return false;
else{
sum /=2;
int n=nums.length;
// dp[i][j] 表示 如果我们取前i个数字,且背包容量为j的情况下,最多能放入多少东西
int dp[][]=new int[n][sum + 1];
// dp[0][0] 为初始状态,表示,没有任何没有东西没有体积,其余部分初始化
for(int i=nums[0];i<=sum;i++){
dp[0][i] = nums[0];
}
//遍历n个数字,即视为n个产品
for(int i=1;i<n;i++){
//加入了这种物品后更新状态
for(int j=nums[i];j<=sum;j++){
dp[i][j]=Math.max(dp[i-1][j], dp[i-1][j-nums[i]]+nums[i]);
}
}
//放满了才能表示正好1/2
if(dp[n-1][sum]==sum)
return true;
else
return false;
}
}
}
补充另一种写法:
public boolean canPartition(int[] nums) {
int sum = ;
for (int num : nums) {
sum += num;
}
if ((sum & ) == ) {
return false;
}
sum /= ;
int n = nums.length;
boolean[][] dp = new boolean[n+][sum+];
for (int i = ; i < dp.length; i++) {
Arrays.fill(dp[i], false);
}
dp[][] = true;
for (int i = ; i < n+; i++) {
dp[i][] = true;
}
for (int j = ; j < sum+; j++) {
dp[][j] = false;
}
for (int i = ; i < n+; i++) {
for (int j = ; j < sum+; j++) {
if (j-nums[i-1] >= 0) {
dp[i][j] = (dp[i-1][j] || dp[i-1][j-nums[i-1]]);
}
}
}
return dp[n][sum];
}
先上一张图:测试数据为nums=[1,3,3,5],判断是否可以分割为两个和为6的数组(不要求连续)。

下面解释一下思路,初始化二维数组dp,初始化全部为false,这个数组中的每一个元素表示:
在前i个元素中,任选其中0~i个元素(可以一个不选,也可以全都选),这些元素的和,是否恰好等于j。
具体来说,dp[0][0]表示前0个元素是否可以组成和为0的情况,这作为前提条件,设置为true。
除这个元素之外的第一列:
dp[1][0],表示前1个元素是否可以组成和为0的情况。答案是:可以组成。只要不选择任何元素,其和值就是0。
dp[2][0],表示前2个元素是否可以组成和为0的情况。答案是:可以组成,只要不选择任何元素,其和值就是0.
dp[3][0],dp[4][0]也是同样道理,均为true。
除dp[0][0]之外的第一行:
dp[0][1],表示前0个元素是否可以组成和为1的情况。答案是:不可以。前0个就是没有任何元素,其和不可能大于0.
dp[0][2]……dp[0][6]也是同样道理,均为false。
下面从dp[1][1]开始判断,一行一行的判断。如图绿色的行。
如果这个元素“上面”是true,那么当前元素就是true。表示当前元素不被选择,可以直接组成和i-1个元素是一样的值。
如果当前元素的列标j>=nums[i-1],则进一步判断。如图,就是比较每一个单元格的“上标注”是否大于等于“右标注”。
如果满足条件,则进一步判断:当前行的上一行的[上标-右标]的元素是否是true。
按照这个转移条件,一行一行的判断,最右下角的元素就是所求结果。表示前i个元素,是否可以组成sum值。
通过分析,可以发现,只要“最后一列”,出现过一次true,那么最终的结果就一定是ture,也就可以提前停止循环了。
具体来说,上图蓝色行的最后一列,即dp[3][6]是true,那么其下面的元素肯定都是true。也就无需后面的判断了。这样理论上可以提高效率。
leetcode416的更多相关文章
- [Swift]LeetCode416. 分割等和子集 | Partition Equal Subset Sum
Given a non-empty array containing only positive integers, find if the array can be partitioned into ...
- 通过netty把百度地图API获取的地理位置从Android端发送到Java服务器端
本篇记录我在实现时的思考过程,写给之后可能遇到困难的我自己也给到需要帮助的人. 写的比较浅显,见谅. 在写项目代码的时候,需要把Android端的位置信息传输到服务器端,通过Netty达到连续传输的效 ...
随机推荐
- 在eclipse中启动java程序的时候,每次都会在一个未设置断点的源码里面,卡断点
可以通过取消这个勾选框,来阻止代码在未设置断点的地方停止 具体位置在:Preferences--Java--Debug
- GANs的回顾
GANs第一篇比较熟悉,不介绍.看看变种. 1) LAPGANs:金字塔,逐步优化生成图片(Deep Generative Image Models using Lapalacian Pyramid ...
- python txt文件常用读写操作
文件的打开的两种方式 f = open("data.txt","r") #设置文件对象 f.close() #关闭文件 #为了方便,避免忘记close掉这个文件 ...
- 4.python字符串格式化
格式化字符串时,Python使用一个字符串作为模板.模板中有格式符,这些格式符为真实值预留位置,并说明真实数值应该呈现的格式.Python用一个tuple将多个值传递给模板,每个值对应一个格式符.py ...
- oracle左关联+号表示方式
1.emp表和dept表 2.emp表中empno为8888的这条数据,没有部门编号,以emp表为主表,左关联查询部门信息sql语句如下: select * from emp e,dept d whe ...
- spring-boot入门总结
1.org.springframework.web.bind.annotation不存在 错误的pom.xml <dependency> <groupId>org.spring ...
- 文件内容比较difflib
#!/usr/bin/env python#-*- coding:utf-8 -*-import difflibimport sys,osos.chdir('E:\\PythonWrok')a = o ...
- JS效果
多标签页效果 tab切换 <!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset ...
- PythonStudy——魔法函数 Magic Methods
魔法函数 python中以双下划线开始和结束的函数(不可自己定义)为魔法函数 调用类实例化的对象的方法时自动调用魔法函数(感觉不需要显示调用的函数都叫) 在自己定义的类中,可以实现之前的内置函数,比如 ...
- PythonStudy——集合 Set
# 空集合:不能用{},因为用来标示空字典 s = set() print(s, type(s)) # 概念:# 1.set为可变类型 - 可增可删# 2.set为去重存储 - set中不能存放重复数 ...