leetcode 494. Target Sum (medium)

  1. DFS 遍历每一种情况,时间复杂度很高…
class Solution
{
  public:
	int findTargetSumWays(vector<int> &nums, int S)
	{
		if (nums.empty())
			return 0;
		int res = 0;
		helper(nums, 0, 0, S, res);
		return res;
	}
	void helper(vector<int> &nums, int curInx, int curNum, int S, int &count)
	{
		if (curInx >= nums.size())
		{
			if (curNum == S)
				++count;
			return;
		}
		helper(nums, curInx + 1, curNum + nums[curInx], S, count);
		helper(nums, curInx + 1, curNum - nums[curInx], S, count);
	}
};
  1. DP
    设P为nums中所有要取正的数的集合,N为所有要取负的数的集合,target为目标值

    				  sum(P) - sum(N) = target
    sum(P) + sum(N) + sum(P) - sum(N) = target + sum(P) + sum(N)
                           2 * sum(P) = target + sum(nums)
    

题目转换成为:求出满足2 * sum(P) = target + sum(nums)等式的数的P集合


class Solution
{
  public:
	int getSums(vector<int> vec)
	{
		int sum = 0;
		for (auto n : vec)
			sum += n;
		return sum;
	}
	int findTargetSumWays(vector<int> &nums, int S)
	{
		int sum = getSums(nums);
		if (S < -sum || S > sum)
			return 0;
		//dp[i][j]表示通过使用第i项来达到和j的可能方法的数量
		vector<vector<int>> dp(nums.size() + 1, vector<int>(sum * 2 + 1, 0));
		dp[0][sum] = 1;
		for (int i = 1; i <= nums.size(); i++)
		{
			for (int j = 0; j <= 2 * sum; j++)
			{
				if (j + nums[i - 1] <= 2 * sum)
				{
					dp[i][j] += dp[i - 1][j + nums[i - 1]];
				}
				if (j - nums[i - 1] >= 0)
				{
					dp[i][j] += dp[i - 1][j - nums[i - 1]];
				}
			}
		}
		return dp[nums.size()][sum + S];
	}
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值