力扣第416题 *** 分割等和子集 c++ 新题 动态规划 中的 01背包问题

news2024/11/25 13:31:59

题目

416. 分割等和子集

中等

相关标签

数组   动态规划

给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。

示例 1:

输入:nums = [1,5,11,5]
输出:true
解释:数组可以分割成 [1, 5, 5] 和 [11] 。

示例 2:

输入:nums = [1,2,3,5]
输出:false
解释:数组不能分割成两个元素和相等的子集。

提示:

  • 1 <= nums.length <= 200
  • 1 <= nums[i] <= 100

思路一二都是基于动态规划来解释的。

不会的可以先去了解了解动态规划是什么,怎么做,模板为什么,等等

然后去了解纯01背包的问题。可以上B站搜,或者本站csdn搜索

这里提供B站视频

代码随想录 动态规划 理论基础icon-default.png?t=N7T8https://www.bilibili.com/video/BV13Q4y197Wg/?spm_id_from=333.337.search-card.all.click&vd_source=fa18c7bb110345953d1f71c2974a5da6代码随想录 01背包 解题方法icon-default.png?t=N7T8https://www.bilibili.com/video/BV1cg411g7Y6/?spm_id_from=333.788&vd_source=fa18c7bb110345953d1f71c2974a5da6代码随想录 01背包 进阶解法 icon-default.png?t=N7T8https://www.bilibili.com/video/BV1BU4y177kY/?spm_id_from=333.788&vd_source=fa18c7bb110345953d1f71c2974a5da6

思路和解题方法 一 (二维数组dp法)

  1. 首先,计算数组 nums 的元素和,并判断是否为奇数,如果是,则无法平分成两个子集,直接返回 false

  2. 计算目标和 target,即每个子集的和应该为 sum / 2,同时判断数组 nums 中的最大值是否大于 target,如果是,则无法平分,直接返回 false

  3. 初始化一个大小为 n * (target+1) 的二维数组 dp,其中 dp[i][j] 表示在前 i 个元素中是否能够找到一些元素的和等于 j

  4. 将第一列 dp[i][0] 全部初始化为 true,因为任何元素都可以不选,使其和为 0。

  5. 将第一行 dp[0][nums[0]] 初始化为 true,因为只有第一个元素可以被选中,使其和为 nums[0]

  6. 从第二个元素开始遍历数组 nums,对于每个元素 nums[i],从 1 到目标和 target 进行遍历,计算 dp[i][j] 的值。

  7. 如果当前元素的值 nums[i] 大于当前的和 j,则不能将该元素加入到和为 j 的子集中,因此 dp[i][j] 的值与 dp[i-1][j] 相等。

  8. 如果当前元素的值 nums[i] 小于等于当前的和 j,则可以将该元素加入到和为 j 的子集中。此时,需要考虑两种情况:选中当前元素或不选中当前元素。因此,dp[i][j] 的值等于 dp[i-1][j]dp[i-1][j-nums[i]]

  9. 循环结束后,返回 dp[n-1][target] 的值,表示在前 n 个元素中是否能够找到一些元素的和等于目标和 target

复杂度

        时间复杂度:

                O(n*target)

时间复杂度:

  • 初始化动态规划数组:O(n * target),其中 n 是数组的长度,target 是目标和的大小。
  • 动态规划过程中的两层循环:O(n * target)。

因此,总体时间复杂度为 O(n * target)。

        空间复杂度

                O(n*target)

 空间复杂度:

  • 动态规划数组:O(n * target),用于存储子问题的解。

因此,总体空间复杂度为 O(n * target)。

c++ 代码 一

class Solution {
public:
    bool canPartition(vector<int>& nums) {
        int n = nums.size();
        if (n < 2) {
            return false;
        }
        int sum = accumulate(nums.begin(), nums.end(), 0); // 计算数组元素的总和
        int maxNum = *max_element(nums.begin(), nums.end()); // 找到数组中的最大值
        if (sum & 1) { // 如果总和为奇数,则无法平分成两个子集
            return false;
        }
        int target = sum / 2; // 目标和为总和的一半
        if (maxNum > target) { // 如果最大值大于目标和,则无法平分
            return false;
        }
        vector<vector<int>> dp(n, vector<int>(target + 1, 0)); // 创建二维动态规划数组
        for (int i = 0; i < n; i++) {
            dp[i][0] = true; // 初始化第一列,表示任何元素都可以不选,使其和为0
        }
        dp[0][nums[0]] = true; // 初始化第一行,只有第一个元素可以被选中,使其和为nums[0]
        for (int i = 1; i < n; i++) { // 从第二个元素开始遍历数组
            int num = nums[i];
            for (int j = 1; j <= target; j++) { // 遍历目标和的范围
                if (j >= num) { // 如果当前和大于等于当前元素的值
                    dp[i][j] = dp[i - 1][j] | dp[i - 1][j - num]; // 可选方案为选中当前元素或不选中当前元素
                } else { // 如果当前和小于当前元素的值
                    dp[i][j] = dp[i - 1][j]; // 只能选择不选中当前元素
                }
            }
        }
        return dp[n - 1][target]; // 返回最后一个元素对应的状态,表示是否能够找到一些元素的和等于目标和
    }
};

思路和解题方法 二(压缩二维 一维)

  1. 首先,定义了一个类 Solution,其中包含了一个公有成员函数 canPartition,该函数接受一个整数数组 nums,并返回一个布尔值。

  2. 在函数内部,首先计算了数组 nums 中所有元素的和,并将结果存储在变量 sum 中。

  3. 接下来,通过判断 sum 是否为奇数,来确定是否可以平分数组。如果 sum 是奇数,则无法平分,直接返回 false

  4. 如果 sum 是偶数,说明可以进行平分。将 sum 除以 2 得到目标值 target,即每个子集的和应该为 target

  5. 初始化一个大小为 10001(为题目数据大小*长度 / 2) 的数组 dp,用于存储动态规划过程中的中间结果。数组 dp 的索引表示当前的和,数组的值表示是否可以组成该和。

  6. 接下来,使用两层循环遍历数组 nums 和目标值 target。外层循环遍历数组 nums,内层循环从 target 开始递减到当前元素的值 nums[i]

  7. 在内层循环中,更新数组 dp 的值。对于每个位置 j,比较 dp[j]dp[j-nums[i]] + nums[i] 的大小,取较大值作为 dp[j] 的新值。这表示在考虑当前元素 nums[i] 时,可以得到的最大和为 dp[j]

  8. 循环结束后,判断数组 dp 的最后一个元素 dp[target] 是否等于 target。如果是,则说明可以找到一个子集使其和为 target,返回 true;否则,返回 false

复杂度

        时间复杂度:

                O(n*target)

        时间复杂度为 O(n×target),其中 n 是数组 nums 的长度,target 是数组 nums 中所有元素的和的一半。因为在内层循环中,需要遍历从 targetnums[i] 的所有可能的和,所以时间复杂度是 O(target),外层循环需要遍历整个数组 nums,所以时间复杂度是 O(n),因此总的时间复杂度是 O(n×target)。

        空间复杂度

                O(target)

        这段代码的空间复杂度为 O(target),因为需要创建一个大小为 target+1 的数组 dp 来存储动态规划的中间结果。

c++ 代码 二

class Solution {
public:
    bool canPartition(vector<int>& nums) {
        int sum = accumulate(nums.begin(), nums.end(), 0); // 计算数组 nums 的所有元素的和
        if (sum % 2 == 1) { // 如果和为奇数,则无法平分成两个子集,直接返回 false
            return false;
        }
        int target = sum / 2; // 计算目标和,即每个子集的和应该为 sum / 2
        vector<bool> dp(target + 1, false); // 初始化一个大小为 target + 1 的布尔型数组 dp,表示能否组成目标和
        dp[0] = true; // 初始状态:目标和为 0 时肯定可以组成
        for (int i = 0; i < nums.size(); ++i) { // 遍历数组 nums
            for (int j = target; j >= nums[i]; --j) { // 从 target 开始递减到 nums[i]
                dp[j] = dp[j] || dp[j - nums[i]]; // 更新 dp[j] 的值
            }
        }
        return dp[target]; // 返回 dp[target] 的值,表示是否能够组成目标和
    }
};

觉得有用的话可以点点赞,支持一下。

如果愿意的话关注一下。会对你有更多的帮助。

每天都会不定时更新哦  >人<  。

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

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

相关文章

qt 系列(二)---qt designer通过设置控件样式表进行背景颜色设置

1. 前言 一般Layouts不可以进行改变样式表&#xff0c;当我们想修改背景样式表&#xff0c;同时又不改变其他控件的颜色时&#xff0c;可以选择List View 控件改变背景颜色。 2. 设置背景 &#xff08;1&#xff09;配置 .qrc 文件 新建mypicture.qrc文件&#xff0c;记事本打…

【刷题宝典NO.0】

目录 素数的判定 打印素数 打印水仙花数 百钱买百坤 输出闰年 逆序打印一个整数的每一位 输出乘法口诀表 数字9出现的次数 二进制1的个数 输出一个整数的偶数位和奇数位的二进制序列 求两个整数的最大公约数 求两个整数的最小公倍数 小乐乐与欧几里得 小…

C#,数值计算——积分方程与逆理论Quad_matrix的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { public class Quad_matrix : UniVarRealMultiValueFun { private int n { get; set; } private double x { get; set; } public Quad_matrix(double[,] a) { this.n a…

适用于 Linux 的 WPF:Avalonia

许多年前&#xff0c;在 WPF 成为“Windows Presentation Foundation”并将 XAML 作为 .NET、Windows 等的 UI 标记语言引入之前&#xff0c;有一个代号为“Avalon”的项目。Avalon 是 WPF 的代号。XAML 现在无处不在&#xff0c;XAML 标准是一个词汇规范。 Avalonia 是一个开…

精品Python空巢老人志愿服务平台慈善捐赠活动报名

《[含文档PPT源码等]精品基于Python的空巢老人志愿服务平台》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功&#xff01; 软件开发环境及开发工具&#xff1a; 开发语言&#xff1a;python 使用框架&#xff1a;Django 前端技术&#…

EasyExcel复杂表头数据导入

目录 表头示例导入代码数据导出 表头示例 导入代码 Overridepublic void importExcel(InputStream inputStream) {ItemExcelListener itemExcelListener new ItemExcelListener();EasyExcel.read(inputStream, ImportItem.class, itemExcelListener).headRowNumber(2).sheet()…

【蓝桥每日一题]-二分类型(保姆级教程 篇2) #砍树 #木材加工

今天讲二分的例题&#xff0c;一道是“砍树”&#xff0c;一道是“木材加工” 目录 题目&#xff1a;砍树 思路1&#xff1a; 思路2&#xff1a; 题目&#xff1a;木材加工 思路&#xff1a; 题目&#xff1a;砍树 思路1&#xff1a; 二分查找&#xff1a;对高度进行二分 二…

关注云栖大会的感受:从工业大脑到全面AI时代的进化

前言 自2009年的地方网站峰会到如今的云栖大会&#xff0c;这个盛大的科技盛事已经走过了一个多十年的漫长历程。这个会议见证了中国科技行业的崛起&#xff0c;也记录了技术的不断演化。而对我来说&#xff0c;首次接触云栖大会是在2020年&#xff0c;当年大会迁移到线上&…

从零开发基于ASM字节码的Java代码混淆插件XHood

项目背景 因在公司负责基础框架的开发设计&#xff0c;所以针对框架源代码的保护工作比较重视&#xff0c;之前也加入了一系列保护措施 例如自定义classloader加密保护&#xff0c;授权license保护等&#xff0c;但都是防君子不防小人&#xff0c;安全等级还比较低 经过调研…

【密评】商用密码应用安全性评估从业人员考核题库(十七)

商用密码应用安全性评估从业人员考核题库&#xff08;十七&#xff09; 国密局给的参考题库5000道只是基础题&#xff0c;后续更新完5000还会继续更其他高质量题库&#xff0c;持续学习&#xff0c;共同进步。 4001 多项选择题 网络和通信安全层面的通信主体一般包括哪些&…

基于Docker-consul容器服务更新与发现

目录 一、什么是服务注册与发现&#xff1a; 二、Docker-consul介绍&#xff1a; 三、consul的关键特性&#xff1a; 四、consul部署&#xff1a; 1.部署规划&#xff1a; 2.consul服务器部署&#xff1a; 2.1 建立consul服务&#xff1a; 启动consul后默认会监听5个端口&a…

管理双因素身份验证的Web应用2FAuth

什么是 2FAuth &#xff1f; 2FAuth 是一种基于 Web 的自托管替代方案&#xff0c;可替代 Google Authenticator 等一次性密码 (OTP) 生成器&#xff0c;专为移动设备和桌面设备设计。 近年来&#xff0c;双因素身份验证变得非常流行&#xff0c;2FA 现在是不可避免且至关重要的…

阿里云ECS经济型e实例ecs.e-c1m1.large性能测评

阿里云服务器ECS经济型e实例2核2G配置规格ecs.e-c1m1.large&#xff0c;CPU采用Intel Xeon Platinum架构处理器&#xff0c;e系列云服务器是阿里云面向个人开发者、学生、小微企业&#xff0c;在中小型网站建设、开发测试、轻量级应用等场景推出的全新入门级云服务器。目前云服…

C++ 类型

4.5//默认double类型 4.5f//float类型 基本内置类型 基本内置类型包含算术类型和空类型&#xff0c;算术类型包含字符、整数型、布尔值和浮点数&#xff0c;空类型不对应具体的值&#xff0c;仅用于一些特殊的场合。 算术类型 分为两类&#xff0c;整型&#xff08;包括字…

艾奇免费KTV电子相册视频制作软件

不得不承认功能特色支持添加导入图形、视频、歌曲、卡啦ok动态歌词字幕文件&#xff1a;图形文件格式支持导入jpg/jpeg/png/bmp/gif等静态图形&#xff1b;视频文件支持导入AVI/MP4/FLV/MTS/MPG/RMVB等几乎所有常见视频文件&#xff1b;歌曲格式支持mp3/wma/acc/ogg/wav等几乎所…

力扣第96题 不同的二叉搜索树 c++ 二叉搜索树 动态规划 + 数学思维

题目 96. 不同的二叉搜索树 中等 相关标签 树 二叉搜索树 数学 动态规划 二叉树 给你一个整数 n &#xff0c;求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种&#xff1f;返回满足题意的二叉搜索树的种数。 示例 1&#xff1a; 输入&#…

NoSQL数据库使用场景以及架构介绍

文章目录 一. 什么是NoSQL&#xff1f;二. NoSQL分类三. NoSQL与关系数据库有什么区别四. NoSQL主要优势和缺点五. NoSQL体系框架 其它相关推荐&#xff1a; 系统架构之微服务架构 系统架构设计之微内核架构 鸿蒙操作系统架构 架构设计之大数据架构&#xff08;Lambda架构、Kap…

Halo勒索病毒:了解最新变种.halo,以及如何保护您的数据

导言&#xff1a; 在当今数字化的世界中&#xff0c;网络威胁不断演变&#xff0c;其中勒索病毒一直是网络犯罪分子的有力武器之一。在这篇文章中&#xff0c;我们将深入介绍.halo勒索病毒&#xff0c;了解它的工作方式&#xff0c;讨论如何恢复被加密的数据文件&#xff0c;并…

【网络协议】聊聊HTTPS协议

前面的文章&#xff0c;我们描述了网络是怎样进行传输数据包的&#xff0c;但是网络是不安全的&#xff0c;对于这种流量门户网站其实还好&#xff0c;对于支付类场景其实容易将数据泄漏&#xff0c;所以安全的方式是通过加密&#xff0c;加密方式主要是对称加密和非对称加密。…

vue3简单写导航anchor示例(支持点击高亮和滚动判断高亮)

1. 点击anchor, 相应的anchorlink高亮 function anchorClick(index) { forceStop.value true; time Date.now(); wheelRef.value.children[index].scrollIntoView({ block: start, behavior: smooth }); // 给一些延时, 再点亮anchor, 同时不再限制scrol…