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

【递归 + 记忆化搜索优化】力扣494. 目标和

给你一个非负整数数组 nums 和一个整数 target 。

向数组中的每个整数前添加 ‘+’ 或 ‘-’ ,然后串联起所有整数,可以构造一个 表达式 :

例如,nums = [2, 1] ,可以在 2 之前添加 ‘+’ ,在 1 之前添加 ‘-’ ,然后串联起来得到表达式 “+2-1” 。
返回可以通过上述方法构造的、运算结果等于 target 的不同 表达式 的数目。

示例 1:
输入:nums = [1,1,1,1,1], target = 3
输出:5
解释:一共有 5 种方法让最终目标和为 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
+1 + 1 + 1 + 1 - 1 = 3

示例 2:
输入:nums = [1], target = 1
输出:1

在这里插入图片描述

方法一:递归

class Solution {
public:int findTargetSumWays(vector<int>& nums, int target) {//正数和 - 要加“-”号的元素和 = target;//正数和 - (未加符号元素总和 - 正数和)= target;// 2正数和 - 未加符号元素总和 = target;// 正数和 = (target + 未加符号元素总和)/ 2;int posNum;int sum = 0;for(int i = 0; i < nums.size(); i++){sum += nums[i];}int sum2 = target + sum;if(sum2 % 2 == 1 || sum2 < 0){return 0;}sum2 /= 2;auto def = [&](auto &&def, int i, long long c){if(i < 0){if(c == 0) return 1;else return 0;}if(c - nums[i] < 0){return def(def, i-1, c);}return def(def, i-1, c) + def(def, i-1, c - nums[i]);};return def(def, nums.size()-1, sum2);}
};

正数和 - 要加“-”号的元素和 = target;
正数和 - (未加符号元素总和 - 正数和)= target;
2正数和 - 未加符号元素总和 = target;
正数和 = (target + 未加符号元素总和)/ 2;

所以我们只需要先计算出sum2,然后来从后往前,根据判断这个元素是否是正数,如果是正数的话,正数和 - 该元素,如果不是的话,正数和不变,继续往前选择元素是否是正数的情况。该方法在时间复杂度上较高,可以考虑使用记忆话搜索避免重复运算。

方法二:记忆化搜索

class Solution {
public:int findTargetSumWays(vector<int>& nums, int target) {//正数和 - 要加“-”号的元素和 = target;//正数和 - (未加符号元素总和 - 正数和)= target;// 2正数和 - 未加符号元素总和 = target;// 正数和 = (target + 未加符号元素总和)/ 2;int posNum;int sum = 0;for(int i = 0; i < nums.size(); i++){sum += nums[i];}int sum2 = target + sum;if(sum2 % 2 == 1 || sum2 < 0){return 0;}sum2 /= 2;vector<vector<int>> memo(nums.size(), vector<int>(sum2+1, -1));auto def = [&](auto &&def, int i, long long c){if(i < 0){if(c == 0) return 1;else return 0;}int& res = memo[i][c];if(res != -1){return res;}if(c - nums[i] < 0){return def(def, i-1, c);}return res = def(def, i-1, c) + def(def, i-1, c - nums[i]);};return def(def, nums.size()-1, sum2);}
};

定义了一个二维向量memo来记忆在第i个元素时,如果还剩下c的时候,有多少种组合方式进行储存,当其他递归运算到这种情况的时候,就不需要继续递归下去,直接使用储存好的数值就行。优化后,计算所有案例时间由499ms -> 7ms。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Linux小组件:makefile
  • 基于单片机的智能风扇设计
  • DLMS/COSEM中的信息安全:安全密钥(中)续2
  • Rust:基于cxx的 C++ 混合编程,字符串参数的转换方法
  • 【JS开源库】基于最小二乘法的离散点拟合圆形,计算圆心坐标和半径
  • 关于redisson的序列化配置
  • vs code 插件: Crabviz
  • MAC上设置快捷打开终端以及如何运用剪切快捷键
  • 编程-设计模式 2:抽象工厂模式
  • YOLO好像也没那么难?
  • Windows图形界面(GUI)-MFC-C/C++ - CSliderCtrl
  • 沪深300股指期货如何操作套期保值?
  • small bird
  • SpringBoot获取resources文件夹下文件并且实现下载
  • 视频懒加载
  • 《Java编程思想》读书笔记-对象导论
  • 【162天】黑马程序员27天视频学习笔记【Day02-上】
  • 【腾讯Bugly干货分享】从0到1打造直播 App
  • 11111111
  • Flex布局到底解决了什么问题
  • Java方法详解
  • js ES6 求数组的交集,并集,还有差集
  • php的插入排序,通过双层for循环
  • Protobuf3语言指南
  • Python学习笔记 字符串拼接
  • Spring Boot MyBatis配置多种数据库
  • 翻译 | 老司机带你秒懂内存管理 - 第一部(共三部)
  • 官方解决所有 npm 全局安装权限问题
  • 普通函数和构造函数的区别
  • 如何借助 NoSQL 提高 JPA 应用性能
  • 视频flv转mp4最快的几种方法(就是不用格式工厂)
  • 适配mpvue平台的的微信小程序日历组件mpvue-calendar
  • 腾讯视频格式如何转换成mp4 将下载的qlv文件转换成mp4的方法
  • 扩展资源服务器解决oauth2 性能瓶颈
  • ​ 全球云科技基础设施:亚马逊云科技的海外服务器网络如何演进
  • ​水经微图Web1.5.0版即将上线
  • ​学习笔记——动态路由——IS-IS中间系统到中间系统(报文/TLV)​
  • # Panda3d 碰撞检测系统介绍
  • # 职场生活之道:善于团结
  • (02)vite环境变量配置
  • (附源码)基于SSM多源异构数据关联技术构建智能校园-计算机毕设 64366
  • (附源码)计算机毕业设计ssm本地美食推荐平台
  • (六)Hibernate的二级缓存
  • (深度全面解析)ChatGPT的重大更新给创业者带来了哪些红利机会
  • (转)Android学习笔记 --- android任务栈和启动模式
  • (转)母版页和相对路径
  • (转)四层和七层负载均衡的区别
  • .java 指数平滑_转载:二次指数平滑法求预测值的Java代码
  • .NET Conf 2023 回顾 – 庆祝社区、创新和 .NET 8 的发布
  • .net refrector
  • @data注解_一枚 架构师 也不会用的Lombok注解,相见恨晚
  • [ C++ ] 继承
  • [ HTML + CSS + Javascript ] 复盘尝试制作 2048 小游戏时遇到的问题
  • [20160902]rm -rf的惨案.txt
  • [20170705]diff比较执行结果的内容.txt