欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

加/减数组中的值得到指定的和 Target Sum

发布时间:2025/7/14 编程问答 39 豆豆
生活随笔 收集整理的这篇文章主要介绍了 加/减数组中的值得到指定的和 Target Sum 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

为什么80%的码农都做不了架构师?>>>   

问题:

You are given a list of non-negative integers, a1, a2, ..., an, and a target, S. Now you have 2 symbols + and -. For each integer, you should choose one from + and - as its new symbol.

Find out how many ways to assign symbols to make sum of integers equal to target S.

Example 1:

Input: nums is [1, 1, 1, 1, 1], S is 3. Output: 5 Explanation: -1+1+1+1+1 = 3 +1-1+1+1+1 = 3 +1+1-1+1+1 = 3 +1+1+1-1+1 = 3 +1+1+1+1-1 = 3 There are 5 ways to assign symbols to make the sum of nums be target 3.

Note:

  • The length of the given array is positive and will not exceed 20.
  • The sum of elements in the given array will not exceed 1000.
  • Your output answer is guaranteed to be fitted in a 32-bit integer.
  • 解决:

    ①  dfs。时间复杂度O(2^n)。

    class Solution { //706ms
        int count = 0;
        public int findTargetSumWays(int[] nums, int S) {
            if (nums == null || nums.length == 0) return 0;
            dfs(nums,S,0,0);
            return count;
        }
        public void dfs(int[] nums,int s,int i,int sum){
            if (i == nums.length){
                if (s == sum){
                    count ++;
                }
                return;
            }
            dfs(nums,s,i + 1,sum + nums[i]);
            dfs(nums,s,i + 1,sum - nums[i]);
        }
    }

    ② 递归解决方案非常慢,因为它的运行时间是指数的。

    原问题等价于:找到一个正数的子集,其余为负数,其总和为target。

    设P为正数子集,N为负数子集。例如:

    给定nums = [1,2,3,4,5]和target = 3,那么一个可能的解决方案是+ 1 - 2 + 3 - 4 + 5 = 3。

    此时正子集是P = [1,3,5],负子集是N = [2,4]。

    下面将其转换为子集总和问题:

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

    所以原来的问题已被转换为子集和问题如下:
    找出nums的一个子集P,使得sum(P)=(target + sum(nums))/ 2 

    class Solution { //17ms
        public int findTargetSumWays(int[] nums, int S) {
            int sum = 0;
            for (int i = 0;i < nums.length;i ++){
                sum += nums[i];
            }
            if (S > sum || (sum + S) % 2 == 1) return 0;//只有该式为偶数时才有符合条件的解
            return subsetSum(nums,(sum + S) / 2);
        }
        public int subsetSum(int[] nums,int S){
            int[] dp = new int[S + 1];
            dp[0] = 1;//初始记录0的位置为1
            for (int i = 0;i < nums.length;i ++){
                for (int j = S;j >= nums[i];j --){
                    dp[j] += dp[j - nums[i]];
                }
            }
            return dp[S];
        }
    }

    转载于:https://my.oschina.net/liyurong/blog/1603737

    总结

    以上是生活随笔为你收集整理的加/减数组中的值得到指定的和 Target Sum的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。