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

leetCode 494. 目标和 + 动态规划 + 记忆化搜索 + 递推 + 空间优化

关于本题我的往期文章:

LeetCode 494.目标和 (动态规划 + 性能优化)二维数组 压缩成 一维数组_呵呵哒( ̄▽ ̄)"的博客-CSDN博客icon-default.png?t=N7T8https://heheda.blog.csdn.net/article/details/133253822


给你一个非负整数数组 nums 和一个整数 target 。向数组中的每个整数前添加 '+' 或 '-' ,然后串联起所有整数,可以构造一个 表达式 :

  • 例如,nums = [2, 1] ,可以在 2 之前添加 '+' ,在 1 之前添加 '-' ,然后串联起来得到表达式 "+2-1" 。

返回可以通过上述方法构造的、运算结果等于 target 的不同 表达式 的数目。


(1)递归 

class Solution {
public:// 递归int findTargetSumWays(vector<int>& nums, int target) {int sum=0,n=nums.size();for(const int & x:nums) sum+=x;if (abs(target) > sum) return 0; // 此时没有方案if ((sum + target) % 2 == 1) return 0; // 此时没有方案if ((sum + target) % 2 == 1) return 0; // 此时没有方案int addTarget = (sum + target) / 2;function<int(int,int)> dfs = [&](int i,int c) -> int {if(i<0) return c==0 ? 1 : 0;// 边界条件:由于要求是恰好组成。恰好情况:当c=0的时候,才能返回1,表示这是一个合法的方案if(c-nums[i]<0) return dfs(i-1,c);return dfs(i-1,c) + dfs(i-1,c-nums[i]);};return dfs(n-1,addTarget);}
};

(2)递归搜索 + 保存计算结果 = 记忆化搜索

class Solution {
public:// 记忆化搜索int findTargetSumWays(vector<int>& nums, int target) {int sum=0,n=nums.size();for(const int & x:nums) sum+=x;if (abs(target) > sum) return 0; // 此时没有方案if ((sum + target) % 2 == 1) return 0; // 此时没有方案int addTarget = (sum + target) / 2;vector<vector<int>> memo(n+1,vector<int>(addTarget+1,-1));function<int(int,int)> dfs = [&](int i,int c) -> int {if(i<0) return c==0 ? 1 : 0;int &res = memo[i][c];if(res != -1) return res;if(c-nums[i]<0) return res=dfs(i-1,c);return res=dfs(i-1,c) + dfs(i-1,c-nums[i]);};return dfs(n-1,addTarget);}
};

(3)1:1 翻译递推

  • dfs(i,c) = dfs(i-1,c) + dfs(i-1,c-w[i])
  • f[i][c] = f[i-1][c] + f[i-1][c-w[i]]
  • f[i+1][c] = f[i][c] + f[i][c-w[i]]

初始化:根据 if(i<0) return c==0 ? 1 : 0; 

  • f 数组初始化为 0
  • dfs(-1,0) = 1 翻译f[0][0]=1

返回最终结果:根据 dfs(n-1,addTarget) 翻译 f[n][addTarget] 

class Solution {
public:// 递推式int findTargetSumWays(vector<int>& nums, int target) {int sum=0,n=nums.size();for(const int & x:nums) sum+=x;if (abs(target) > sum) return 0; // 此时没有方案if ((sum + target) % 2 == 1) return 0; // 此时没有方案int addTarget = (sum + target) / 2;vector<vector<int>> f(n+1,vector<int>(addTarget+1,0));f[0][0]=1;for(int i=0;i<n;i++) {for(int c=0;c<=addTarget;c++) {if(c-nums[i]<0) f[i+1][c]=f[i][c];else f[i+1][c]=f[i][c] + f[i][c-nums[i]];}}return f[n][addTarget];}
};

  • 优化空间

方式一:二维数组优化

  • f[(i+1)%2][c]=f[i%2][c] + f[i%2][c-nums[i]];
class Solution {
public:// 递推式 + 优化空间int findTargetSumWays(vector<int>& nums, int target) {int sum=0,n=nums.size();for(const int & x:nums) sum+=x;if (abs(target) > sum) return 0; // 此时没有方案if ((sum + target) % 2 == 1) return 0; // 此时没有方案int addTarget = (sum + target) / 2;vector<vector<int>> f(2,vector<int>(addTarget+1,0));f[0][0]=1;for(int i=0;i<n;i++) {for(int c=0;c<=addTarget;c++) {if(c-nums[i]<0) f[(i+1)%2][c]=f[i%2][c];else f[(i+1)%2][c]=f[i%2][c] + f[i%2][c-nums[i]];}}return f[n%2][addTarget];}
};

方式二:一维数组优化

  • f[i+1][c]=f[i][c] + f[i][c-nums[i]];
  • f[c]=f[c] + f[c-nums[i]];
class Solution {
public:// 递推式 + 优化空间int findTargetSumWays(vector<int>& nums, int target) {int sum=0,n=nums.size();for(const int & x:nums) sum+=x;if (abs(target) > sum) return 0; // 此时没有方案if ((sum + target) % 2 == 1) return 0; // 此时没有方案int addTarget = (sum + target) / 2;vector<int>f(addTarget+1,0);f[0]=1;for(int i=0;i<n;i++) {for(int c=addTarget;c>=nums[i];c--) {f[c]=f[c] + f[c-nums[i]];}}return f[addTarget];}
};// 也可以写成这样
for(const int& x:nums) {for(int c=addTarget;c>=x;c--) {f[c]=f[c] + f[c-x];}
}

相关文章:

  • 致远OA wpsAssistServlet任意文件读取漏洞复现 [附POC]
  • Pytest UI自动化测试实战实例
  • DI93a HESG440355R3 通过其Achilles级认证提供网络安全
  • 如何当好一面面试官?
  • 个体诊所电子处方系统有哪些?个体门诊处方管理系统
  • Jenkins自动化部署简单配置
  • Go错误包装
  • React18新特性?
  • 【书籍篇】Spring实战第4版 第1部分 Spring的核心
  • 【qemu逃逸】HWS2017-FastCP
  • Paddle炼丹炉炸了Unexpected BUS error encountered in DataLoader worker
  • 计算机网络第4章-网络层(1)
  • 通讯网关软件032——利用CommGate X2OPC实现OPC客户端访问Modbus TCP设备
  • 1,Opencv常用结构
  • ENVI波段合成
  • [case10]使用RSQL实现端到端的动态查询
  • 【140天】尚学堂高淇Java300集视频精华笔记(86-87)
  • 【comparator, comparable】小总结
  • 【node学习】协程
  • 【vuex入门系列02】mutation接收单个参数和多个参数
  • 345-反转字符串中的元音字母
  • Android框架之Volley
  • Javascript弹出层-初探
  • MySQL-事务管理(基础)
  • zookeeper系列(七)实战分布式命名服务
  • 从零开始的无人驾驶 1
  • 回顾 Swift 多平台移植进度 #2
  • 基于Mobx的多页面小程序的全局共享状态管理实践
  • 简单实现一个textarea自适应高度
  • 可能是历史上最全的CC0版权可以免费商用的图片网站
  • 漂亮刷新控件-iOS
  • 使用Tinker来调试Laravel应用程序的数据以及使用Tinker一些总结
  • 世界编程语言排行榜2008年06月(ActionScript 挺进20强)
  • 数组大概知多少
  • 智能网联汽车信息安全
  • 最简单的无缝轮播
  • Spark2.4.0源码分析之WorldCount 默认shuffling并行度为200(九) ...
  • ​secrets --- 生成管理密码的安全随机数​
  • # Swust 12th acm 邀请赛# [ E ] 01 String [题解]
  • (cos^2 X)的定积分,求积分 ∫sin^2(x) dx
  • (层次遍历)104. 二叉树的最大深度
  • (附源码)计算机毕业设计SSM教师教学质量评价系统
  • (四)搭建容器云管理平台笔记—安装ETCD(不使用证书)
  • (算法二)滑动窗口
  • (原創) 人會胖會瘦,都是自我要求的結果 (日記)
  • (转)memcache、redis缓存
  • .NET C#版本和.NET版本以及VS版本的对应关系
  • .NET Project Open Day(2011.11.13)
  • .NET/C# 编译期能确定的字符串会在字符串暂存池中不会被 GC 垃圾回收掉
  • .Net6使用WebSocket与前端进行通信
  • .Net各种迷惑命名解释
  • .NET中的十进制浮点类型,徐汇区网站设计
  • .stream().map与.stream().flatMap的使用
  • @RequestBody与@ModelAttribute
  • [ vulhub漏洞复现篇 ] struts2远程代码执行漏洞 S2-005 (CVE-2010-1870)