import java.util.*; /** * NC243 目标和 * @author d3y1 */ public class Solution { private int result = 0; /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param nums int整型一维数组 * @param target int整型 * @return int整型 */ public int findTargetSumWays (int[] nums, int target) { return solution1(nums, target); // return solution2(nums, target); // return solution3(nums, target); } /** * 动态规划 * * sum表示所有整数的和 * A表示所有前面加'+'号的整数和 * B表示所有前面加'-'号的整数和 * 依题意,可知: * A + B = sum * A + (-B) = target * => 2A = sum + target * * 转化为 求整数和为A的组合个数(方案数) * * dp[j]表示可累加为A的组合个数(方案数) * * dp[j] = dp[j] + dp[j-nums[i-1]] , j >= nums[i-1] * * @param nums * @param target * @return */ private int solution1(int[] nums, int target){ int n = nums.length; if(n == 0){ return 0; } int sum = 0; for(int i=0; i<n; i++){ sum += nums[i]; } // 2A = sum + target 奇数 if((sum+target)%2 != 0){ return 0; } int A = (sum + target) / 2; int[] dp = new int[A+1]; dp[0] = 1; for(int i=1; i<=n; i++){ // 每个整数只能选择一次 倒序遍历避免重复选取 for(int j=A; j>=nums[i-1]; j--){ dp[j] += dp[j-nums[i-1]]; } } return dp[A]; } /** * 动态规划 * * sum表示所有整数的和 * A表示所有前面加'+'号的整数和 * B表示所有前面加'-'号的整数和 * 依题意,可知: * A + B = sum * A + (-B) = target * => 2A = sum + target * * 转化为 求整数和为A的组合个数(方案数) * * dp[i][j]表示用nums前i个数可累加为A的组合个数(方案数) * * { dp[i-1][j] , j < nums[i-1] * dp[i][j] = { * { dp[i-1][j] + dp[i-1][j-nums[i-1]] , j >= nums[i-1] * * @param nums * @param target * @return */ private int solution2(int[] nums, int target){ int n = nums.length; if(n == 0){ return 0; } int sum = 0; for(int i=0; i<n; i++){ sum += nums[i]; } // 2A = sum + target 奇数 if((sum+target)%2 != 0){ return 0; } int A = (sum + target) / 2; int[][] dp = new int[n+1][A+1]; dp[0][0] = 1; for(int i=1; i<=n; i++){ for(int j=0; j<=A; j++){ dp[i][j] = dp[i-1][j]; if(j >= nums[i-1]){ dp[i][j] += dp[i-1][j-nums[i-1]]; } } } return dp[n][A]; } /** * dfs * @param nums * @param target * @return */ private int solution3(int[] nums, int target){ if(nums.length == 0){ return 0; } dfs(0, 0, nums, target); return result; } /** * 递归 * @param level * @param sum * @param nums * @param target */ private void dfs(int level, int sum, int[] nums, int target){ if(level == nums.length){ if(sum == target){ result++; } return; } dfs(level+1, sum+nums[level], nums, target); dfs(level+1, sum-nums[level], nums, target); } }