Javascript 目标总和未输出正确的值

Javascript 目标总和未输出正确的值,javascript,algorithm,Javascript,Algorithm,我正在尝试解决目标和问题() 我能够通过基本案例,但是([0,1],1)案例失败 试着去理解我做错了什么,以及我如何去纠正它 var findTargetSumWays=函数(nums,总计){ 常数res=[]; 让str=nums.join(“”); 助手(str,,,0); 函数助手(str、curStr、sum){ 如果(str.length==0)返回; 如果(总和+数字(str)==总数){ res.push(`${curStr}+${str}`); 返回; } if(总和-数字(

我正在尝试解决目标和问题()

我能够通过基本案例,但是(
[0,1],1
)案例失败

试着去理解我做错了什么,以及我如何去纠正它

var findTargetSumWays=函数(nums,总计){
常数res=[];
让str=nums.join(“”);
助手(str,,,0);
函数助手(str、curStr、sum){
如果(str.length==0)返回;
如果(总和+数字(str)==总数){
res.push(`${curStr}+${str}`);
返回;
}
if(总和-数字(str)==总数){
res.push(`${curStr}-${str}`);
返回;
}

例如(假设i=0;i您的DFS想法可以用于足够小的输入(问题的约束可能支持)但我不明白为什么要将数字列表转换为字符串,而不是直接对数字执行DFS。要查找当前方法中的错误,我建议将中间步骤写入控制台,以查看它们是否如您所期望的那样

下面是一些公认的代码,其思想是构建可能的总和,并通过包括我们在以前的迭代中已经使用的方法来计算达到这些总和的方法。希望代码能把它弄清楚

函数f(nums,S){
设和={0:1}

对于(让i=0;i我认为,在您的算法中,将数组转换为字符串是冗余的,因为您可以直接使用算法的第二步,即dfs/递归,如下所示(对不起,我不懂javascript,但我希望它更容易阅读)

int find_it(向量&a,int i,int n,int&sum,int sum_直到现在)
{
如果(i==n)
{
if(sum\u到现在==sum)
返回1;
返回0;
}
int first=find_it(a,i+1,n,sum,sum_直到现在-a[i]);
first+=找到它(a,i+1,n,sum,sum,直到现在的sum+a[i]);
先返回;
}
整数findTargetSumWays(向量和整数,整数和){
int n=nums.size();
int ways=find_it(nums,0,n,sum,0);
返回方式;
} 
但是如果你想到优化,你会看到递归/dfs树正在生成许多重复递归函数,我们如何避免重复递归函数,动态规划可以使用,如果我们知道不同递归函数形成的状态,这里是i(当前位置)和sum_,直到现在(我的意思是,我们可以通过这两个参数在递归树中使用两个不同的递归函数,所以在动态规划中使用状态),因此,如果我们存储这些状态组合,就相当于保存函数信息,因此下次我们不必再次进入已访问/已保存函数的递归树。有一件事,一些人认为这不是动态编程,而是dfs+记忆,但也有许多人认为这是自上而下的动态pr编程为递归也会探索子问题,然后保存不同的状态

以下是优化版本:

vector<vector<int>>dp
int find_it(vector<int> & a , int i , int n , int &sum , int sum_till_now)
{
    if(i == n)
    {
        if(sum_till_now == sum)
            return 1;
        return 0;
    }
    if(dp[i][sum_till_now + 1000] != -1)
        return dp[i][sum_till_now + 1000];

    int first = find_it(a , i + 1 , n , sum ,  sum_till_now - a[i]);
    first += find_it(a , i + 1 , n , sum , sum_till_now + a[i]);

    return dp[i][sum_till_now + 1000] = first;
}
int findTargetSumWays(vector<int>& nums, int sum) {
    int n = nums.size();
    dp = vector<vector<int>> (n, vector<int>(2001 , -1));
    int ways = find_it(nums , 0 , n , sum , 0);
    return ways;   
}
vectordp
int find_it(向量&a,int i,int n,int&sum,int sum_直到现在)
{
如果(i==n)
{
if(sum\u到现在==sum)
返回1;
返回0;
}
如果(dp[i][sum\u to\u now+1000]!=-1)
返回dp[i][sum_to_now+1000];
int first=find_it(a,i+1,n,sum,sum_直到现在-a[i]);
first+=找到它(a,i+1,n,sum,sum,直到现在的sum+a[i]);
返回dp[i][sum\u to\u now+1000]=第一个;
}
整数findTargetSumWays(向量和整数,整数和){
int n=nums.size();
dp=向量(n,向量(2001,-1));
int ways=find_it(nums,0,n,sum,0);
返回方式;
}

有一件事,我在使用dp值或将值赋给dp时,在sum\u中加了1000,因为给定的最大sum可以达到1000,所以通过对称性,很明显,负值中的最大sum也只能达到-1000,所以由于数组或向量索引不能有负索引,所以我现在将sum\u增加了1000,使其成为非negative.

如果输入数组中的某些数字有多个数字,该怎么办?如果我为我编写的这个问题添加一个非常简单的解决方案,可以吗?
int find_it(vector<int> & a , int i , int n , int &sum , int sum_till_now)
{
    if(i == n)
    {
        if(sum_till_now == sum)
            return 1;
        return 0;
    }
    int first = find_it(a , i + 1 , n , sum ,  sum_till_now - a[i]);
    first += find_it(a , i + 1 , n , sum , sum_till_now + a[i]);

    return first;
}
int findTargetSumWays(vector<int>& nums, int sum) {
    int n = nums.size();
    int ways = find_it(nums , 0 , n , sum , 0);
    return ways;  
} 
vector<vector<int>>dp
int find_it(vector<int> & a , int i , int n , int &sum , int sum_till_now)
{
    if(i == n)
    {
        if(sum_till_now == sum)
            return 1;
        return 0;
    }
    if(dp[i][sum_till_now + 1000] != -1)
        return dp[i][sum_till_now + 1000];

    int first = find_it(a , i + 1 , n , sum ,  sum_till_now - a[i]);
    first += find_it(a , i + 1 , n , sum , sum_till_now + a[i]);

    return dp[i][sum_till_now + 1000] = first;
}
int findTargetSumWays(vector<int>& nums, int sum) {
    int n = nums.size();
    dp = vector<vector<int>> (n, vector<int>(2001 , -1));
    int ways = find_it(nums , 0 , n , sum , 0);
    return ways;   
}