作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/


题目地址:https://leetcode.com/problems/target-sum/description/

题目描述

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:

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

题目大意

给了一个数组和一个target number,现在要给这个数组的每个数添加上+或-, 使得求和的结果是target number。求满足条件的组合个数。

解题方法

动态规划

这个题让我扔了三个月,今天又看了两个小时,动态规划不很懂就是这个后果!

刚开始用的dfs做的,遍历所有的结果,统计满足结果的个数就可以了。没错,超时了。超时的代码如下:

class Solution(object):
def findTargetSumWays(self, nums, S):
"""
:type nums: List[int]
:type S: int
:rtype: int
"""
def helper(index, acc):
if index == len(nums):
if acc == S:
return 1
else:
return 0
return helper(index + 1, acc + nums[index]) + helper(index + 1, acc - nums[index])
return helper(0, 0)

其实一般能用dfs解决的题目,如果题目只要求满足条件的数字而不是所有的结果,那么dfs会超时。解决方法其实基本只有一条路:动态规划。

我们定义了一个二维数组,这个二维数组dp[i][j]的意义是我们从最开始的位置到第i个位置上能够成和为j的组合有多少种,因为求和之后数的范围不确定,所以数组中保存的是字典,字典保存的是到i位置能求得的和为某个数的个数。

所以从左到右进行遍历,在每个位置都把前一个位置的字典拿出来,看前一个位置的所有能求得的和。和当前的数值分别进行加减操作,就能得出新一个位置能求得的和了。

状态转移方程是:

dp[0][0] = 1;
dp[i + 1][x + nums[i]] += dp[i][x];
dp[i + 1][x - nums[i]] += dp[i][x];
注意:其中x是在前一个位置能够成的和。

要注意一点是,dp初始不能采用下面方式:

dp = [collections.defaultdict(int)] * (_len + 1)

这种初始化方式会使每个位置的元素其实是同一个字典。

代码如下:

class Solution:
def findTargetSumWays(self, nums, S):
"""
:type nums: List[int]
:type S: int
:rtype: int
"""
_len = len(nums)
dp = [collections.defaultdict(int) for _ in range(_len + 1)]
dp[0][0] = 1
for i, num in enumerate(nums):
for sum, cnt in dp[i].items():
dp[i + 1][sum + num] += cnt
dp[i + 1][sum - num] += cnt
return dp[_len][S]

这个题的C++代码如下,这里的代码说明了对于unordered_map,在C++里面调用一个不存在的key的时候,会使用默认初始化的版本,类似于Python的collections.defaultdict()。比如这里调用的+=符号,在左侧不存在的时候,会初始化0。

class Solution {
public:
int findTargetSumWays(vector<int>& nums, int S) {
const int N = nums.size();
vector<unordered_map<int, int>> dp(N + 1);
dp[0][0] = 1;
for (int i = 0; i < N; i ++) {
for (auto m : dp[i]) {
dp[i + 1][m.first + nums[i]] += m.second;
dp[i + 1][m.first - nums[i]] += m.second;
}
}
return dp[N][S];
}
};

日期

2018 年 5 月 28 日 —— 太阳真的像日光灯~
2018 年 12 月 31 日 —— 2018年最后一天!

【LeetCode】494. Target Sum 解题报告(Python & C++)的更多相关文章

  1. LeetCode 1 Two Sum 解题报告

    LeetCode 1 Two Sum 解题报告 偶然间听见leetcode这个平台,这里面题量也不是很多200多题,打算平时有空在研究生期间就刷完,跟跟多的练习算法的人进行交流思想,一定的ACM算法积 ...

  2. LN : leetcode 494 Target Sum

    lc 494 Target Sum 494 Target Sum You are given a list of non-negative integers, a1, a2, ..., an, and ...

  3. [LeetCode] 494. Target Sum 目标和

    You are given a list of non-negative integers, a1, a2, ..., an, and a target, S. Now you have 2 symb ...

  4. Leetcode 494 Target Sum 动态规划 背包+滚动数据

    这是一道水题,作为没有货的水货楼主如是说. 题意:已知一个数组nums {a1,a2,a3,.....,an}(其中0<ai <=1000(1<=k<=n, n<=20) ...

  5. LeetCode: Minimum Path Sum 解题报告

    Minimum Path Sum Given a m x n grid filled with non-negative numbers, find a path from top left to b ...

  6. 【LeetCode】120. Triangle 解题报告(Python)

    [LeetCode]120. Triangle 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址htt ...

  7. LeetCode 2 Add Two Sum 解题报告

    LeetCode 2 Add Two Sum 解题报告 LeetCode第二题 Add Two Sum 首先我们看题目要求: You are given two linked lists repres ...

  8. 【LeetCode】Permutations II 解题报告

    [题目] Given a collection of numbers that might contain duplicates, return all possible unique permuta ...

  9. 【LeetCode】Island Perimeter 解题报告

    [LeetCode]Island Perimeter 解题报告 [LeetCode] https://leetcode.com/problems/island-perimeter/ Total Acc ...

随机推荐

  1. Beautiful Soup解析库的安装和使用

    Beautiful Soup是Python的一个HTML或XML的解析库,我们可以用它来方便地从网页中提取数据.它拥有强大的API和多样的解析方式.官方文档:https://www.crummy.co ...

  2. MybatisPlus使用Wrapper实现查询功能

    Wrapper---条件查询器 :使用它可以实现很多复杂的查询 几个案例 环境: 参照博客:MybatisPlus入门程序 1.条件查询 1.1 查询name不为空的用户,并且邮箱不为空的用户,年龄大 ...

  3. 内网穿透—使用 frp 实现内外网互通

    前言 什么是内网穿透? 内网穿透,又叫 NET 穿透,是计算机用语.用通俗的说法就是你家里的个人电脑,可以直接被外网的人访问.例如你在公司,不通过远程工具,直接也可以访问到家里的电脑(本文章特指 we ...

  4. Jumpserver堡垒机容器化部署

    JumpServer 是符合 4A 的专业运维安全审计系统. 前提条件 已部署docker Jumpserver 对外需要开放 80 443 和 2222 端口 服务器.数据库.redis 等依赖组件 ...

  5. 分布式事务(3)---强一致性分布式事务Atomikos实战

    分布式事务(1)-理论基础 分布式事务(2)---强一致性分布式事务解决方案 分布式事务(4)---最终一致性方案之TCC 前面介绍强一致性分布式解决方案,这里用Atomikos框架写一个实战的dem ...

  6. day17 阶段测验

    题目 1.找出/proc/meminfo文件中以s开头的行,至少用三种方式忽略大小写 有以下几种方法: [root@localhost ~]# grep -iE "^s" /pro ...

  7. Spark基础:(二)Spark RDD编程

    1.RDD基础 Spark中的RDD就是一个不可变的分布式对象集合.每个RDD都被分为多个分区,这些分区运行在分区的不同节点上. 用户可以通过两种方式创建RDD: (1)读取外部数据集====> ...

  8. HDFS【Namenode、SecondaryNamenode、Datanode】

    目录 一. NameNode和SecondaryNameNode 1.NN和2NN 工作机制 2. NN和2NN中的fsimage.edits分析 3.checkpoint设置 4.namenode故 ...

  9. 大数据学习day21-----spark04------1. 广播变量 2. RDD中的cache 3.RDD的checkpoint方法 4. 计算学科最受欢迎老师TopN

    1. 广播变量  1.1 补充知识(来源:https://blog.csdn.net/huashetianzu/article/details/7821674) 之所以存在reduce side jo ...

  10. 颜色RGB值对照表

    转载自 http://www.91dota.com/?p=49# 常用颜色的RGB值及中英文名称   颜  色    RGB值 英文名 中文名   #FFB6C1 LightPink 浅粉红   #F ...