494.目标和
class Solution {
private int count;
public int findTargetSumWays(int[] nums, int target) {
this.count = 0;
process(nums,target,0);
return count;
}
public void process(int[] nums, int rest,int index){
if(index == nums.length){
if(rest==0){
count++;
}
return;
}
process(nums,rest-nums[index],index+1);
process(nums,rest+nums[index],index+1);
}
}
这是本题的暴力回溯实现。
但是注意process(nums,rest-nums[index],index+1);这里rest的下一个值是可大可小的所以不能往一个方向去递推。但是所有元素的和是固定的,所给的目标值也是固定的。由下图可以推出,所有带加号的值和带减号的值是固定的。
class Solution {
public int findTargetSumWays(int[] nums, int target) {
int sum = 0;
for(int i=0; i < nums.length;i++){
sum+=nums[i];
}
// 目标值不能大于总和 目标值可能为负数
if(Math.abs(target)>sum) return 0;
if((target+sum)%2!=0) return 0; // 因为taget是加部分和减部分的和,sum是都是加部分。二者相加,一部分数被算了两遍,除不尽,一定是没合适结果,返回0;
int pos = (sum+target)/2;
int neg = (sum-target)/2;
int capcity = Math.min(pos, neg); // 取pos和neg中的较小者,以使得dp空间最小
int[][] dp = new int[nums.length+1][capcity+1];
// (+或者-)的目标值为0的时候,并且也num也为空的时候,有一个。
dp[0][0] = 1;
for(int i = 1;i <= nums.length;i++){
for(int j = 0; j <= capcity; j++){
if(j<nums[i-1]){
dp[i][j] = dp[i-1][j];
}else{
// i 代表第num中第ige,从一开始算所以取i-1
dp[i][j] = dp[i-1][j]+dp[i-1][j-nums[i-1]];
}
}
}
return dp[nums.length][capcity];
}
}
参考:https://www.bilibili.com/video/BV1o8411j73x/?spm_id_from=333.337.search-card.all.click&vd_source=46d50b5d646b50dcb2a208d3946b1598
作者:flix
链接:https://leetcode.cn/problems/target-sum/solutions/1410230/by-flix-rkb5/
作者:静默虚空
欢迎任何形式的转载,但请务必注明出处。
限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)