码迷,mamicode.com
首页 > 其他好文 > 详细

力扣494

时间:2020-03-13 11:31:18      阅读:48      评论:0      收藏:0      [点我收藏+]

标签:code   big   行号   ||   暴力   str   color   复杂度   pack   

给定一个非负整数数组,a1, a2, ..., an, 和一个目标数,S。现在你有两个符号 + 和 -。对于数组中的任意一个整数,你都可以从 + 或 -中选择一个符号添加在前面。

返回可以使最终数组和为目标数 S 的所有添加符号的方法数。

  1. 数组非空,且长度不会超过20。
  2. 初始的数组的和不会超过1000
  3. 保证返回的最终结果能被32位整数存下。

来源:力扣(LeetCode)
解法一:暴力(超时)

不贴代码了,求出全部可能性,并遍历,得到目标为S的数量。时间复杂度2的N次方。

解法二:递归

注意,初始的数组的和不会超过1000。这句话及其关键。定义一个数组,列号为nums数组的前几个数。行号为这几个数组合之和,值为这个值的数量。由于组合之和可能为负数,且范围在[-1000,1000],所以一共需要有2001行,第0行代表和为-1000。

递归关系式为

getRes(res,nums.length,S,nums)=getRes(res, length-1, s-nums[length-1],nums)+getRes(res, length-1, s+nums[length-1],nums)。
代码如下(注意要对行号进行判断,有可能溢出):
 1 package Leetcode;
 2 public class findTargetSumWays {
 3     public int findTargetSumWays(int[] nums, int S) {
 4         if(S>1000||S<-1000){return 0;}
 5         int[][] res = new int[2001][2];
 6 
 7         res[nums[0]+1000][1]+=1;
 8         res[-nums[0]+1000][1]+=1;
 9 
10         int count = getRes(res,nums.length,S,nums);
11         return count;
12     }
13 
14     private int getRes(int[][] res, int length, int s,int[] nums) {
15         if(length==1){
16             if(s>1000||s<-1000){return 0;}
17             return res[s+1000][1];
18         }
19         int small = getRes(res, length-1, s-nums[length-1],nums);
20         int big = getRes(res, length-1, s+nums[length-1],nums);
21         return small+big;
22     }
23 }

解法三:dp

其实这道题dp和递归的思想是一样的,只是dp是从前往后推,递归是从后往前推。代码如下

 1 class Solution {
 2      public int findTargetSumWays(int[] nums, int S) {
 3         int[][] dp = new int[nums.length][2001];
 4         dp[0][nums[0] + 1000] = 1;
 5         dp[0][-nums[0] + 1000] += 1;
 6         for (int i = 1; i < nums.length; i++) {
 7             for (int sum = -1000; sum <= 1000; sum++) {
 8                 if (dp[i - 1][sum + 1000] > 0) {
 9                     dp[i][sum + nums[i] + 1000] += dp[i - 1][sum + 1000];
10                     dp[i][sum - nums[i] + 1000] += dp[i - 1][sum + 1000];
11                 }
12             }
13         }
14         return S > 1000 ? 0 : dp[nums.length - 1][S + 1000];
15     }
16 }

 

力扣494

标签:code   big   行号   ||   暴力   str   color   复杂度   pack   

原文地址:https://www.cnblogs.com/zhangbochao/p/12485240.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!