当前位置: 首页 > news >正文

[100天算法】-目标和(day 79)

题目描述

给定一个非负整数数组,a1, a2, ..., an, 和一个目标数,S。现在你有两个符号 + 和 -。对于数组中的任意一个整数,你都可以从 + 或 -中选择一个符号添加在前面。返回可以使最终数组和为目标数 S 的所有添加符号的方法数。示例:输入:nums: [1, 1, 1, 1, 1], S: 3
输出:5
解释:-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一共有5种方法让最终目标和为3。提示:数组非空,且长度不会超过 20 。
初始的数组的和不会超过 1000 。
保证返回的最终结果能被 32 位整数存下。来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/target-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路 1: DP

简单理解一下题目就是,我们要从数组中选出一个正数集,然后剩下的数字自动变成了一个负数集,这两个集合的和要刚好等于目标数 S。

换句话说,我们要从原数组中选出一个子集,满足元素的和为 target(这个 target 不是原题中的 S),只要确定这个 target,剩下就是 0-1 背包问题的套路了。

已知:

  • 正数集 + 负数集 = S
  • 正数集 - 负数集 = sum

sum 是原数组的和。

可得:

  • 正数集 = (S + sum) / 2

所以 (S + sum) / 2 就是我们要找的 target。

复杂度

  • 时间复杂度:$O(len*(sum+S)/2)$,len 是数组长度,sum 是数组元素和,S 是目标数。
  • 空间复杂度:$O((sum+S)/2)$。

代码

JavaScript Code

/*** @param {number[]} nums* @param {number} S* @return {number}*/
var findTargetSumWays = function (nums, S) {const sum = nums.reduce((a, b) => a + b, 0);if (sum < S) return 0;const sumOfPositives = (sum + S) / 2;if (sumOfPositives % 1 !== 0) return 0;const dp = Array(sumOfPositives + 1).fill(0);// target 为 0 时,正数集为空// 也就是只有给所有数字都加上 - 号这一种方法dp[0] = 1;for (const n of nums) {for (let i = sumOfPositives; i >= n; i--) {dp[i] = dp[i] + dp[i - n];}}return dp[sumOfPositives];
};

思路 2: DFS

DFS 枚举所有排列组合,计算组合的和,如果满足和等于 S 则结果++。

复杂度

  • 时间复杂度:$O(2^n)$,n 是数组长度。
  • 空间复杂度:$O(logn)$。

代码

JavaScript Code

/*** @param {number[]} nums* @param {number} S* @return {number}*/
var findTargetSumWays = function (nums, S) {const dfs = (nums, i, sum) => {if (sum === S && i === nums.length) return 1;if (i > nums.length) return 0;return (dfs(nums, i + 1, sum + nums[i]) + dfs(nums, i + 1, sum - nums[i]));};return dfs(nums, 0, 0);
};

相关文章:

  • 【JavaEE】Servlet API 详解(HttpServlet类)
  • office365 outlook邮件无法删除
  • windows安装maven,配置环境变量
  • Java实现音频转码,WAV、MP3、AMR互转
  • WordPress 媒体库文件夹管理插件 FileBird v5.5.4和谐版下载
  • 机器人制作开源方案 | 智能家庭防护机器人
  • 51单片机应用从零开始(三)
  • 保护您的Google账号安全:检查和加固措施
  • 【Shell脚本12】Shell 输入/输出重定向
  • Clickhouse学习笔记(13)—— Materialize MySQL引擎
  • opencv(1):创建和显示窗口, 读取保存图片
  • Zigbee智能家居方案设计
  • 第三章 栈和队列【24王道数据结构笔记】
  • 滴滴 Redis 异地多活的演进历程
  • 网络安全准入技术之MAC VLAN
  • 网络传输文件的问题
  • 345-反转字符串中的元音字母
  • Apache的基本使用
  • canvas绘制圆角头像
  • C语言笔记(第一章:C语言编程)
  • JDK 6和JDK 7中的substring()方法
  • MYSQL如何对数据进行自动化升级--以如果某数据表存在并且某字段不存在时则执行更新操作为例...
  • Python_网络编程
  • vue--为什么data属性必须是一个函数
  • 从setTimeout-setInterval看JS线程
  • 反思总结然后整装待发
  • 给初学者:JavaScript 中数组操作注意点
  • 回顾 Swift 多平台移植进度 #2
  • 基于 Ueditor 的现代化编辑器 Neditor 1.5.4 发布
  • 基于组件的设计工作流与界面抽象
  • 解决iview多表头动态更改列元素发生的错误
  • 容器服务kubernetes弹性伸缩高级用法
  • 试着探索高并发下的系统架构面貌
  • 写代码的正确姿势
  • 一个普通的 5 年iOS开发者的自我总结,以及5年开发经历和感想!
  • 译米田引理
  • 远离DoS攻击 Windows Server 2016发布DNS政策
  • 栈实现走出迷宫(C++)
  • 如何通过报表单元格右键控制报表跳转到不同链接地址 ...
  • ​linux启动进程的方式
  • $var=htmlencode(“‘);alert(‘2“); 的个人理解
  • (Java数据结构)ArrayList
  • (剑指Offer)面试题41:和为s的连续正数序列
  • (力扣)1314.矩阵区域和
  • (六) ES6 新特性 —— 迭代器(iterator)
  • (深入.Net平台的软件系统分层开发).第一章.上机练习.20170424
  • (五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境
  • (循环依赖问题)学习spring的第九天
  • (转)Linq学习笔记
  • ... fatal error LINK1120:1个无法解析的外部命令 的解决办法
  • .NET 8.0 发布到 IIS
  • .NET CF命令行调试器MDbg入门(三) 进程控制
  • .Net MVC + EF搭建学生管理系统
  • .NET 程序如何获取图片的宽高(框架自带多种方法的不同性能)
  • .net 打包工具_pyinstaller打包的exe太大?你需要站在巨人的肩膀上-VC++才是王道