zoukankan      html  css  js  c++  java
  • 494. Target Sum

    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.
    

    Constraints:

    • 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.
    class Solution {
        int res = 0;
        public int findTargetSumWays(int[] nums, int S) {
            if(nums.length == 0) return 0;
            dfs(nums, S, 0, 0);
            return res;
        }
        public void dfs(int[] nums, int S, int pos, int cur){
            if(pos == nums.length) {
                if(cur == S) res++;
                return;
            }
            dfs(nums, S, pos + 1, cur + nums[pos]);
            dfs(nums, S, pos + 1, cur - nums[pos]);
        }
    }

    1. dfs, 每一步都可以加减,所以从cur0开始,每次dfs都可以±。

    显然 还有更快的方法

    public int findTargetSumWays(int[] nums, int S) {
          
          int sum = 0;
          for(int n: nums){
            sum += n;
          }
          if (S < -sum || S > sum) { return 0;}
            
          int[][] dp = new int[nums.length + 1][ 2 * sum + 1];
          dp[0][0 + sum] = 1; // 0 + sum means 0, 0 means -sum,  check below graph
          for(int i = 1; i <= nums.length; i++){
            for(int j = 0; j < 2 * sum + 1; j++){
              
              if(j + nums[i - 1] < 2  * sum + 1) 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.length][sum + S];
        }

    背包法,普通0/1背包是选或不选,这个是选它或者选它的负数,所以dp [ i ][ j ] = dp[i-1][j-nums[i-1]] + dp[i-1][j + nums [ i - 1];

    dp[ i ][ j ]意思是:为了达到sum j,使用了前i个元素,所以上面的转移方程显然(个鬼)

    因为j的范围是 -sum ---- 0 ----sum,所以我们默认dp[ 0 ][ sum]相当于起点0,所以dp[ 0 ][ 0 ] 就代表-sum,dp 【i】【sum+S】就是我们所要求的。

     总结:

    1. we can use DFS, if we reach the end of the array and the current number == target, we count it as a valid one, then all we need to do is recursively call dfs method to continue two operations ( plus and minus)

    2. This is a 0/1 knapsack question, normally we can choose or not choose the current value, but in this question we can choose the positive value and negative value, which is pretty same

    so we initiate a dp array with dimension of dp[nums.length+1][2 * sum + 1], sum is the sum of nums array. The reason we do this is our range of knapsack volume is -sum to sum ( the bound of we can use this array).

    Then  dp [ i ][ j ] = dp[i-1][j-nums[i-1]] + dp[i-1][j + nums [ i - 1]; dp means the number of ways for first i-th element to reach a sum j.

  • 相关阅读:
    Asp.net 程序连接orcle如果在安装 32 位 Oracle 客户端组件的情况下以 64 位模式运行,
    Navicat 远程连接 Oracle11g 数据库报错 No listener 的问题
    springMVC中@DateTimeFormat 失效的处理
    单例设计模式中懒汉式线程安全的处理
    ajax同步请求
    vue.js在标签属性中拼接字符串
    vue.js进行遍历
    html页面之间的传值
    URL编码和解码的一个小问题(JS方法和JAVA方法)
    SolrJ的配置及使用
  • 原文地址:https://www.cnblogs.com/wentiliangkaihua/p/13321174.html
Copyright © 2011-2022 走看看