416. 分割等和子集
此题做时没有思路,其实此题就是01背包,不能将此题的本质看透,
背包的容量即数组和的一半,(此处可以进行剪枝,即若数组和不是偶数,说明一定不存在,直接返回false)物品的重量和价值即是数组中每一项的数值,就是看背包装满时的此时物品的最大价值是不是为目标值–>数组所有数和的一半
class Solution {
public boolean canPartition(int[] nums) {
int sum=0;
for(int i=0;i<nums.length;i++){
sum+=nums[i];
}
if(sum % 2 != 0) return false;
int target = sum/2;
int[] dp = new int[target+1];
//此处用了进阶版的01背包问题解法
for(int i=0;i<nums.length;i++){
for(int j=target;j>=nums[i];j--){
dp[j] = Math.max(dp[j],dp[j-nums[i]] + nums[i]);
}
}
return dp[target] == target;
}
}
1049. 最后一块石头的重量 II
思路:和上题大体思路相同
class Solution {
public int lastStoneWeightII(int[] stones) {
int n = stones.length;
int sum=0;
for(int i=0;i<n;i++){
sum+=stones[i];
}
int target = sum/2;
//抽象为背包容量为一半时的最大容量与剩余容量的差即为最小的可能重量
int[] dp = new int[target+1];
for(int i=0;i<n;i++){
for(int j=target;j>=stones[i];j--){
dp[j] = Math.max(dp[j],dp[j-stones[i]]+stones[i]);
}
}
//注意;这里有个小细节,因为求target时是向下取整,
//所有剩下一份的重量要大于等于dp[target]的重量
return sum - 2*dp[target];
}
}
509. 斐波那契数
没难度,纯属一乐
方法一-->菜鸟思维法
class Solution {
public int fib(int n) {
if(n == 0) return 0;
if(n == 1) return 1;
int num1 = 0;
int num2 = 1;
int num3 = 0;
for(int i=0;i<n-1;i++){
num3 = num1+num2;
num1 = num2;
num2 = num3;
}
return num3;
}
}
方法二-->动态规划思维法
class Solution {
public int fib(int n) {
if(n == 0) return 0;
if(n == 1) return 1;
int[] dp = new int[n+1];
dp[0] = 0;
dp[1] = 1;
for(int i=2;i<n+1;i++){
dp[i] = dp[i-1] + dp[i-2];
//不用再更新数值了
// dp[i-2] = dp[i-1];
// dp[i-1] = dp[i];
}
return dp[n];
}
}