2915. 和为目标值的最长子序列的长度
题目链接:2915. 和为目标值的最长子序列的长度
难度:中等
刷题状态:1刷
新知识:
解题过程
思考
示例 1:
输入:nums = [1,2,3,4,5], target = 9 输出:3 解释:总共有 3 个子序列的和为 9 :[4,5] ,[1,3,5] 和 [2,3,4] 。最长的子序列是 [1,3,5] 和 [2,3,4] 。所以答案为 3 。
该题中nums每个元素只能用一次,所以选择从后往前遍历
直接手搓出来了,用的是和昨天一样的套路
题解分析
参考题解链接:【模板】恰好装满型 0-1 背包(Python/Java/C++/Go)
手搓答案(无非废话版)
/**
* @param {number[]} nums
* @param {number} target
* @return {number}
*/
var lengthOfLongestSubsequence = function(nums, target) {
let dp=Array(target+1).fill(-Infinity)
dp[0]=0
for(let i=0;i<nums.length;i++){
for(let j=target;j>=nums[i];j--){
dp[j]=Math.max(dp[j],dp[j-nums[i]]+1)
}
}
return dp[target]==-Infinity?-1:dp[target]
};
总结
也可以直接看昨天的链接LeetCode灵神算法题库JS(107/200)第五天|377. 组合总和 Ⅳ|2466. 统计构造好字符串的方案数|2266. 统计打字方案数-优快云博客
416. 分割等和子集
题目链接:416. 分割等和子集
难度:中等
刷题状态:1刷
新知识:
解题过程
思考
示例 1:
输入:nums = [1,5,11,5] 输出:true 解释:数组可以分割成 [1, 5, 5] 和 [11] 。
分成两部分 part1 part2
那么 part1=part2 part1+part2=sum(nums)
=> part1=sum/2
问题变成了找到几个元素使part1=sum/2
每个元素只能用1次 从后往前遍历
手搓出来了
题解分析
参考题解链接:
LeetCode灵神算法题库JS(107/200)第五天|377. 组合总和 Ⅳ|2466. 统计构造好字符串的方案数|2266. 统计打字方案数-优快云博客
手搓答案(无非废话版)
/**
* @param {number[]} nums
* @return {boolean}
*/
var canPartition = function(nums) {
let sum=nums.reduce((acc,num)=>acc+num,0)
if(sum%2) return false
let target=sum/2
console.log(target)
let dp=Array(target+1).fill(0)
dp[0]=1
for(let i=0;i<nums.length;i++){
for(let j=target;j>=nums[i];j--){
dp[j]+=dp[j-nums[i]]
}
}
return dp[target]==0?false:true
};

总结
和上一题一样的套路
518. 零钱兑换 II
题目链接:518. 零钱兑换 II
难度:中等
刷题状态:1刷
新知识:
解题过程
思考
示例 1:
输入:amount = 5, coins = [1, 2, 5] 输出:4 解释:有四种方式可以凑成总金额: 5=5 5=2+2+1 5=2+1+1+1 5=1+1+1+1+1
coins中元素可以重复使用 用从前往后遍历
一样的套路,看手搓答案
题解分析
参考题解链接:
LeetCode灵神算法题库JS(107/200)第五天|377. 组合总和 Ⅳ|2466. 统计构造好字符串的方案数|2266. 统计打字方案数-优快云博客
手搓答案(无非废话版)
/**
* @param {number} amount
* @param {number[]} coins
* @return {number}
*/
var change = function(amount, coins) {
let dp=Array(amount+1).fill(0)
dp[0]=1
for(let i=0;i<coins.length;i++){
for(let j=coins[i];j<=amount;j++){
dp[j]+=dp[j-coins[i]]
}
}
return dp[amount]
};
总结
套路
279. 完全平方数
题目链接:279. 完全平方数
难度:中等
刷题状态:1刷
新知识:
- `
Math.sqrt()` 开方
解题过程
思考
示例 1:
输入:n =12输出:3 解释:12 = 4 + 4 + 4
要返回的是最少的数量,
这题难点在于我们要自己构建nums[1,4,9,16...]
所以先把n开方取小值,再从1开始遍历构建nums
nums中的元素可重复使用 从前往后遍历
先手搓了一版
/**
* @param {number} n
* @return {number}
*/
var numSquares = function(n) {
let max=Math.floor(Math.sqrt(n))
let nums=[]
for(let i=1;i<=max;i++) nums.push(i*i)
let dp=Array(n+1).fill(Infinity)
dp[0]=0
for(let i=0;i<nums.length;i++){
for(let j=nums[i];j<=n;j++){
dp[j]=Math.min(dp[j],dp[j-nums[i]]+1)
}
}
return dp[n]
};
nums还有可以改进的地方,可以不用构建,直接在循环中判断,见手搓答案中
题解分析
参考题解链接:
LeetCode灵神算法题库JS(107/200)第五天|377. 组合总和 Ⅳ|2466. 统计构造好字符串的方案数|2266. 统计打字方案数-优快云博客
手搓答案(无非废话版)
var numSquares = function(n) {
let dp=Array(n+1).fill(Infinity)
dp[0]=0
for(let i=0;i*i<=n;i++){
for(let j=i*i;j<=n;j++){
dp[j]=Math.min(dp[j],dp[j-i*i]+1)
}
}
return dp[n]
}
总结
注意可以改进的部分
for(let i=0;i*i<=n;i++){
for(let j=i*i;j<=n;j++){



被折叠的 条评论
为什么被折叠?



