LeetCode 377——组合总和 Ⅳ

news2024/12/27 18:38:32

阅读目录

    • 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) 就是无穷的了。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

React ant 点击导航条闪烁

问题 : 点击当前位置会出现闪一下的效果 另一种点击方式 , 不会闪 原因 : 没有传递具体的参数给点击事件 , 导致在函数内部无法准确判断要展示哪个子菜单&#xff0c;可能导致页面状态的短暂变化&#xff0c;出现闪烁效果 代码 : // 左侧子菜单弹出const showSonMenu routeK…

Word 画三线表模板---一键套用

1、制作三线表 1&#xff09;设置为无边框 选中表格&#xff0c;点击「右键」——「边框」——「无框线」。 2&#xff09;添加上下边框线 选中表格后&#xff0c;点击【右键】——【表格属性】——【边框和底纹】&#xff0c;边框线选择【1.5磅】&#xff0c;然后点击【上框…

(WSI分类)WSI分类文献小综述 2024

2024的WSI分类。 Multiple Instance Learning Framework with Masked Hard Instance Mining for Whole Slide Image Classification &#xff08;ICCV2024&#xff09; 由于阳性组织只占 Gi- gapixel WSI 的一小部分&#xff0c;因此现有的 MIL 方法直观上侧重于通过注意力机…

算法:day1

前缀树&#xff1a; class Trie {private Trie[] childrenIndex;// 该节点下一个可能出现的所有字符的链接private boolean isEnd;// 该节点是否是最后一个字符// 初始化根节点public Trie() {childrenIndex new Trie[26];isEnd false;}public void insert(String word) {// …

ArcGIS Desktop使用入门(四)工具箱——属性域

系列文章目录 ArcGIS Desktop使用入门&#xff08;一&#xff09;软件初认识 ArcGIS Desktop使用入门&#xff08;二&#xff09;常用工具条——标准工具 ArcGIS Desktop使用入门&#xff08;二&#xff09;常用工具条——编辑器 ArcGIS Desktop使用入门&#xff08;二&#x…

从ChatGPT到多模态大模型:现状与未来(多模态)

ChatGPT 训练的核心技术主要包括: 预训练语言模型;有监督微调;基于人类反馈的 强 化 学 习 (ReinforcementLearningfrom Human Feedback,RLHF) 首先,通过自监督预训练使语言模型从大规模语料库中学习语言规律,具备基础 理解和生成能力;然后,通过构造指令微调数据集 并对模型进…

部署GlusterFS群集

目录 一、部署GlusterFS群集 1. 服务器节点分配 2. 服务器环境&#xff08;所有node节点上操作&#xff09; 2.1 关闭防火墙 2.2 磁盘分区&#xff0c;并挂载 2.3 修改主机名&#xff0c;配置/etc/hosts文件 3. 安装、启动GlusterFS&#xff08;所有node节点上操作&…

34. UE5 RPG实现鼠标点击移动

在前面&#xff0c;我们实现过使用键盘按键wasd去实现控制角色的移动&#xff0c;现在&#xff0c;我们实现了InputAction按键触发&#xff0c;后面&#xff0c;实现一下通过鼠标点击地面实现角色移动。 我们将实现两种效果的切换&#xff0c;如果你点击地面快速松开&#xff0…

​如何使用 ArcGIS Pro 制作带贴图建筑

对于用GIS软件制作三维建筑&#xff0c;很多时候都是制作的建筑体块&#xff0c;这里为大家介绍一下怎么使用 ArcGIS Pro 制作带贴图的建筑&#xff0c;希望能对你有所帮助。 数据来源 教程所使用的数据是从水经微图中下载的建筑数据&#xff0c;除了建筑数据&#xff0c;常见…

浏览器工作原理与实践--渲染流水线:CSS如何影响首次加载时的白屏时间

在上一篇文章中我们详细介绍了DOM的生成过程&#xff0c;并结合具体例子分析了JavaScript是如何阻塞DOM生成的。那本文我们就继续深入聊聊渲染流水线中的CSS。因为CSS是页面中非常重要的资源&#xff0c;它决定了页面最终显示出来的效果&#xff0c;并影响着用户对整个网站的第…

大话设计模式——18.策略模式(Strategy Pattern)

简介 是一系列算法的封装&#xff0c;即做的事情相同&#xff08;方法名称相同&#xff09;但是实现的方式不同&#xff0c;以相同方式调用所有的算法&#xff0c;减少算法与使用算法的耦合。直接调用方法。 UML图 应用场景 Java AWT中的LayoutManager&#xff08;布局管理器&…

开源铱塔切换MySQL数据库启动报异常

1.错误日志&#xff1a; 铱塔切换数据库配置为MySQL之后&#xff0c;启动后报错如下&#xff1a; SqlExceptionHelper - Table iotkit.task_info doesnt exist SqlExceptionHelper - Table iotkit.rule_info doesnt exist SqlExceptionHelper - Table iotkit.device_info does…

微软称在量子纠错领域取得大进展,量子超级计算机能在2033年问世?

大数据产业创新服务媒体 ——聚焦数据 改变商业 自从物理学家费曼&#xff08;Richard Feynman&#xff09;在80年代首次提出了利用量子力学原理进行计算的概念&#xff0c;无数科学家就梦想着用量子计算重塑未来。可惜现实往往“磕磕绊绊”&#xff0c;40多年过去了&#xff…

Element UI前端页面

1.前端 如何用ElementUI快速搭建一个前端网页模板&#xff0c;接下来会详细讲解&#xff01; 1.Container布局 这是ElementUI官网提供的能快速搭建一个网页的基本布局模式&#xff0c;以下是一个网页的基本架构模式&#xff0c;主要分为三大块&#xff1a; AsideHeaderMain 我…

SpringBoot快速入门笔记(7)

文章目录 VueRouter前端路由1、简介2、RouterDemo3、子路由4、动态路由 VueRouter前端路由 1、简介 Vue的单页面应用是基于路由和组件的&#xff0c;不同组件的切换需要前端路由完成 vue-router3只能结合vue2&#xff0c;vue-router4只能结合vue3 安装 npm install vue-router…

FreeGPT3.5 开源软件

GPT-3.5不需要付费&#xff0c;也不需要注册用户&#xff0c;可以直接使用了&#xff0c;官方彻底开放了API接口。 该API政策一放开&#xff0c;GitHub很快就已经出现了一个开源项目FreeGPT35&#xff0c;可以自动生成key调用GPT3.5的API接口&#xff0c;再也用不着注册账号和申…

Hololens2远程音视频通话与AR远程空间标注,基于OpenXR+MRTK3+WebRTC实现

Hololens2远程音视频通话与AR远程空间标注 使用Unity2021.3.21版本开发&#xff0c;基于OpenXRMRTK3.0WebRTC实现。 &#xff08;1&#xff09;通过视频获取视频帧的矩阵的方法可以参考&#xff1a;https://learn.microsoft.com/zh-cn/windows/mixed-reality/develop/advanced…

强化学习:基础开发

基本就是把看到有用的资料整合在一起了 资料 https://blog.csdn.net/weixin_48878618/article/details/133590646 https://blog.csdn.net/weixin_42769131/article/details/104783188?ops_request_misc%257B%2522request%255Fid%2522%253A%2522166792845916800182132771%25…

【azure笔记 1】容器实例管理python sdk封装

容器实例管理python sdk封装 测试结果 说明 这是根据我的需求写的&#xff0c;所以有些参数是写死的&#xff0c;比如cpu核数和内存&#xff0c;你可以根据你的需要自行修改。前置条件&#xff1a; 当前环境已安装python3.8以上版本和azure cli并且已经登陆到你的账户 依赖安…

Angular 使用DomSanitizer

跨站脚本Cross-site scripting 简称XSS&#xff0c;是代码注入的一种&#xff0c;是一种网站应用程序的安全漏洞攻击。它允许恶意用户将代码注入到网页上&#xff0c;其他用户在使用网页时就会收到影响&#xff0c;这类攻击通常包含了HTML和用户端脚本语言&#xff08;JS&…