LeetCode 377——组合总和 Ⅳ

阅读目录

    • 1. 题目
    • 2. 解题思路
    • 3. 代码实现

1. 题目

2. 解题思路

此题一看应该就是需要用到动态规划算法,假设我们以 f[d]表示总和为 d 的元素组合的个数,首先,我们遍历 nums 数组,

如果有 nums[i] < target,那么组合中第一个元素我们放置 nums[i],组合中余下元素的排列总个数也就变成了子问题 f[target - nums[i]]

如果有 nums[i] = target,那么组合中只能放置 nums[i]这一个元素。

3. 代码实现

于是,我开始实现了第一版代码,完全就照着上面的解题思路来写,使用递归。

class Solution {
public:
    int combinationSum4(vector<int>& nums, int target) {
        
        int ret = 0;
        for (int i = 0; i < nums.size(); ++i) {
            if (nums[i] < target) {
                ret += combinationSum4(nums, target-nums[i]);
            }
            else if (nums[i] == target) {
                ret += 1;
            }
        }
        return ret;
    }
};

很可惜,没有通过全部测试用例,超时了。

超出时间限制 10 / 16 个通过的测试用例

这里,计算 f[target - nums[i]]的时候有可能存在大量重复,比如,nums=[1, 2, 3, 4], target=5,第一个元素我们放置 2 时,需要计算 f(3)。然后,如果前两个元素我们都放置 1 时,也需要计算 f(3)

所以,一个很自然的思路就是把已经计算过的 f(d)记录下来,下次遇到可以直接用。

class Solution {
public:
    
    int combinationSum4(vector<int>& nums, int target) {
        static vector<int> target_ret(1001, -1);
        int ret = 0;
        for (int i = 0; i < nums.size(); ++i) {
            if (nums[i] < target) {
                int left = target - nums[i];
                if (target_ret[left] == -1) {
                    target_ret[left] = combinationSum4(nums, left); 
                }
                ret += target_ret[left];
            }
            else if (nums[i] == target) {
                ret += 1;
            }
        }
        return ret;
    }
};

于是,我定义了一个静态数组,全部初始化为 -1,计算一个 f(d) 后就把它记录下来,下次直接使用,不用再递归去调用一次函数。

但是,这次直接变成解答错误了。我把错误的用例单独拿出来测试,答案是对的。去网上一查,原来 LeetCode 会用这同一个类去测试所有的测试用例,那么我的静态数组就会受到前一个测试用例的影响,所以,答案也就是错的了,此路看来也不通!

那就只能手动递推了,因为我们最终要计算 f(target) ,而 f(target) 可能依赖于 f(target-1)、f(target-2)....f(1),所以我们就从 1 开始,一个一个往后计算 f(d) 即可。

class Solution {
public:
    
    int combinationSum4(vector<int>& nums, int target) {
        vector<int> target_ret(target+1, 0);

        for (int j = 1; j <= target; ++j) {
            for (int i = 0; i < nums.size(); ++i) {
                if (nums[i] < j) {
                    int left = j - nums[i];
                    target_ret[j] += target_ret[left];
                }
                else if (nums[i] == j) {
                    target_ret[j] += 1;
                }
            }
        }
        return target_ret[target];
    }
};

很不幸,还是出错了,看起来是整型数超出表示范围了,一个简单的思路是把 int 换成 unsigned int,终于成功了!

Line 16: Char 35: runtime error: signed integer overflow: 2147483647 + 1 cannot be represented in type ‘int’ (solution.cpp)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior prog_joined.cpp:25:35

class Solution {
public:
    
    int combinationSum4(vector<int>& nums, int target) {
        vector<unsigned int> target_ret(target+1, 0);
        for (int j = 1; j <= target; ++j) {
            for (int i = 0; i < nums.size(); ++i) {
                if (nums[i] < j) {
                    int left = j - nums[i];
                    target_ret[j] += target_ret[left];
                }
                else if (nums[i] == j) {
                    target_ret[j] += 1;
                }
            }
        }
        return target_ret[target];
    }
};

要细究为什么会越界的话,其实题目描述里特别说明了 :

题目数据保证答案符合 32 位整数范围。

但是这里只是说 f(target) 不会越界,我们从 1 遍历到 target 的某个中间变量可能越界了,然后这个中间变量实际上是用不到的。

比如,nums=[2, 6, 9], target=15f(14) 是不会用到的,但是我们也会计算它。

时间复杂度为 O ( t a r g e t ∗ n u m s . s i z e ( ) ) O(target*nums.size()) O(targetnums.size()),空间复杂度为 O ( t a r g e t ) O(target) O(target)

如果数组中存在负数的话,会存在一个包含正数和负数的序列,它们的和为 0,也就是说,可以无限添加这个序列,而和保持不变,这样,f(target) 就是无穷的了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/529607.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

阿赵UE学习笔记——26、动画混合空间

阿赵UE学习笔记目录   大家好&#xff0c;我是阿赵。   继续学习虚幻引擎的使用。之前学习了通过蓝图直接控制动画播放&#xff0c;或者通过动画状态机去控制播放。这次来学习一种比较细致的动画控制播放方式&#xff0c;叫做动画混合空间。 一、使用的情景 假设我们现在需…

06_vim编辑器

为什么要使用vi和vim vi和vim是最常用的文本编辑工具&#xff0c;就像Windows上的笔记本一样。在linux中修改任何文件&#xff0c;不管是nginx配置还是系统配置文件&#xff0c;都会用到vi和vim命令。 很多软件的编辑接口实际上调用的是vi。 vim是vi的高级版&#xff0c;操作…

SpringBoot中注册Bean的方式汇总

文章目录 ComponentScan Componet相关注解BeanImportspring.factories总结Configuration和Component的主要区别&#xff1f;Bean是不是必须和Configuration一起使用&#xff1f;Import导入配置类有意义&#xff1f;出现异常&#xff1a;java.lang.NoClassDefFoundError: Could…

Scrapy框架spider类异常处理

说明&#xff1a;仅供学习使用&#xff0c;请勿用于非法用途&#xff0c;若有侵权&#xff0c;请联系博主删除 作者&#xff1a;zhu6201976 一、捕获Request所有网络相关异常 在spider类中&#xff0c;我们构造Request对象或FormRequest对象时&#xff0c;可传递参数errback回调…

小米强硬表态!敦促智己公司立即道歉 不接受个人轻描淡写的非正式道歉

快科技4月9日消息&#xff0c;在智己L6的发布会上&#xff0c;小米SU7成了“主角”之一&#xff0c;方方面面进行了对标和暗讽。 甚至官方还将智己L6和小米SU7 Max的各项参数与价格直接对比&#xff0c;引起了不小关注。 小米强硬表态&#xff01;敦促智己公司立即道歉 不接受…

electron打包Vue前端

Electron-Forge 打包Vue项目 效果&#xff1a;electronforge可将前端静态页面打包成.exe、.deb和.rpm等&#xff0c;能适配各种平台 示例&#xff1a;Windows环境下将前端 Vue 项目打包成exe文件 打包后的 exe 文件 运行 exe 文件 一、项目准备 开源项目 RouYi 下载 本…

【分布式事务与分库分表】

文章目录 &#x1f50a;博主介绍&#x1f964;本文内容分布式事务介绍分布式事务解决方案1. 2PC&#xff08;Two Phase Commit&#xff09;方案2. JTA/XA规范实现3. Seata AT模式实现4. TCC实现使用hmily实现TCC Spring Cloud Alibaba项目中整合Seata来实现分布式事务管理1. **…

C语言面试题之环路检测

环路检测 实例要求 1、给定一个链表&#xff0c;如果它是有环链表&#xff0c;实现一个算法返回环路的开头节点&#xff1b;2、若环不存在&#xff0c;请返回NULL&#xff1b;3、如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在…

Java项目:基于Springboot+vue实现的中国陕西民俗前后台管理系统设计与实现(源码+数据库+毕业论文)

一、项目简介 本项目是一套基于Springbootvue实现的中国陕西民俗管理系统设计与实现设 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界…

Docker 搭建私有镜像仓库

一、镜像仓库简介 Docker的镜像仓库是一个用于存储和管理Docker镜像的中央位置。镜像仓库的主要作用是提供一个集中的地方&#xff0c;让用户可以上传、下载、删除和共享Docker镜像。镜像仓库又可以分为公共镜像仓库和私有仓库镜像仓库&#xff1a; 公共镜像仓库 Docker Hub 是…

20240326-2-LightGBM面试题

LightGBM面试题 1. 简单介绍一下LightGBM&#xff1f; LightGBM是一个梯度 boosting 框架&#xff0c;使用基于学习算法的决策树。 它可以说是分布式的&#xff0c;高效的。 从 LightGBM 名字我们可以看出其是轻量级&#xff08;Light&#xff09;的梯度提升机&#xff08;G…

从0到1实现RPC | 07a 更新pom依赖方式

当前工程目录进行编译时 mvn clean install&#xff0c;会报错。原因是 rpc-core和rpc-demo-api不是一个spring boot项目&#xff0c;没有启动类。 默认在根pom文件中引入了spring的parent&#xff0c;导致子模块都是web项目&#xff0c;所以需要更新pom文件。 在根目录的pom文…

直播系统的短视频直播源码,带有多功能后台系统的直播短视频平台 APP 源码。

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 此源码是一个直播系统&#xff0c;集直播、短视频等功能&#xff0c;根据市场趋势开发并推出思乐直播APP&#xff0c;APP功能丰富且可在后台管理系统进行配置&#xff0c;做到按需求来…

UE5、CesiumForUnreal实现建筑白模生长动画效果

文章目录 1.实现目标2.实现过程2.1 实现原理2.2 具体代码2.3 应用测试3.参考资料1.实现目标 在上篇文章加载本地建筑轮廓GeoJson数据生成建筑白模的基础上,本文通过材质“顶点偏移”实现建筑白模生长效果,GIF动图如下所示: 2.实现过程 常用的实现建筑生长效果的方式有两种,…

随机潮流应对不确定性?计及分布式发电的配电系统随机潮流计算程序代码!

前言 随着分布式电源在电力系统中所占比例的不断扩大,研究分布式发电对系统稳态运行的影响势在必行。带分布式发电的潮流计算常常用来评估其并网后对系统的影响&#xff0c;同时它也是分析分布式发电对电网稳定性的影响等其他理论研究工作的基础。然而&#xff0c;许多分布式发…

Feature Pyramid Networks for object detection

FPN 总述1.引言2.相关工作3. Feature Pyramid NetworksBottom-up pathwayTop-down pathway and lateral connections 4. 应用用于 RPN用于 Fast R-CNN 核心代码复现FPN网络结构ResNet Bottleneck完整代码 总述 下图中&#xff0c;蓝色边框表示的是特征图&#xff0c;边框越粗表…

视频号带货真的能成为2024年赚钱的新风口吗?

随着互联网技术的飞速发展和消费者购物习惯的不断转变&#xff0c;视频号带货这一新兴商业模式逐渐走进大众视野。在短视频平台日益火爆的今天&#xff0c;很多人都在思考&#xff0c;视频号带货是否会成为2024年赚钱的新风口? 首先&#xff0c;视频号带货具备成为新风口的潜力…

【项目】棋海争锋

&#x1f3a5; 个人主页&#xff1a;Dikz12&#x1f4d5;格言&#xff1a;吾愚多不敏&#xff0c;而愿加学欢迎大家&#x1f44d;点赞✍评论⭐收藏 目录 项目介绍 WebSocket介绍 使用 项目创建 数据库设计 用户模块 登录接口 注册接口 获取用户信息接口 匹配模块 …

4.9学习总结

一.File类 (一).概述: File 类的对象代表操作系统的文件&#xff08;文件、文件夹&#xff09;,File 类提供了诸如&#xff1a;创建文件对象代表文件&#xff0c;获取文件信息&#xff08;大小、修改时间&#xff09;、删除文件、创建文件&#xff08;文件夹&#xff09;等功…

安卓四大组件——Service篇

1.作用 长时间位于后台&#xff08;无界面&#xff09;完成用户指定操作 1.1两类状态 &#xff08;a&#xff09;started&#xff08;启动&#xff09;&#xff1a;当应用程序组件&#xff08;如activity&#xff09;调用startService()方法启动服务时&#xff0c;服务处于sta…