力扣494

Posted zhangbochao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了力扣494相关的知识,希望对你有一定的参考价值。

给定一个非负整数数组,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的主要内容,如果未能解决你的问题,请参考以下文章

2021-12-24:划分字母区间。 字符串 S 由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。返回一个表示每个字符串片段的长度的列表。 力扣763。某大厂面试

LeetCode 494. Target Sum

Codeforces Round #494 (Div. 3) F. Abbreviation

哟,在面向监狱编程呢!

494. Target Sum

第四周课堂测试补做