【LeetCode】416. 分割等和子集

news2024/11/15 20:43:38

416. 分割等和子集(中等)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

方法一: 0-1背包问题的普通解法

  1. 思路

    • 首先,对题目做一个等价转换: 「是否可以从数组中选择一些正整数,使这些数的和等于整个数组元素和的一半」。

    • 这样就可以看作一个 0-1背包问题, 它的特点是:每个数只能用一次。解决的基本思路是:物品一个个选,容量也一点一点增加去考虑

    • 具体的做法是:画一个 n * (mid+1) 的表格,其中 n 是物品的个数, mid 是背包的容量。n 行表示一个个物品考虑, mid+1 多出来的那一列,表示容量从 0 开始考虑。

    • 状态定义dp[i][j] 表示从数组的 [0,i] 这个子区间内挑选一些正整数,每个数只能用一次,使这些数的和恰好等于 j

    • 状态转移方程:很多时候,状态转移方程的思考角度是 分类讨论 ,对于 0-1 背包问题就是 「考虑当前的数字选或者不选」。

      • 不选择 nums[i] ,如果在 [0, i-1] 这个子区间内已经有一部分元素,使得它们的和为 j ,那么 dp[i][j] = true;
      • 选择 nums[i] ,如果在 [0,i] 这个子区间内就得找到一部分元素,使得它们的和为 j-nums[i]。
    • 初始化条件

      • j-nums[i] 作为数组下标,需要保证大于等于 0,因此 nums[i] <= j ;
      • 当 j == nums[i] 的时候,一定能够保证 dp[i][j] = true;
    • 完整的状态转移方程在这里插入图片描述

  2. 代码

    class Solution {
    public:
        bool canPartition(vector<int>& nums) {
            int n = nums.size();
            int sum = accumulate(nums.begin(), nums.end(), 0);
            // 特判:如果sum为奇数 则不符合要求
            if(sum % 2) return false;
            int mid = sum / 2;
            // dp[0][0] = false : 因为数组中不含0 因此元素和不可能为0
            vector<vector<bool>> dp(n, vector<bool>(mid + 1, false));
            // 先填表格的第0行,第一个数只能让容积为它自己的背包装满
            if(nums[0] <= mid){
                dp[0][nums[0]] = true;
            }
            for(int i=1; i<n; ++i){
                for(int j=0; j<=mid; ++j){
                    // 直接把上一行的结果抄下来,之后再修正
                    dp[i][j] = dp[i-1][j];
                    if(j > nums[i]){
                        dp[i][j] = dp[i-1][j - nums[i]] || dp[i-1][j];
                    }
                    else if(j == nums[i]){
                        dp[i][j] = true;
                        continue;
                    }
                }
            }
            return dp[n-1][mid];
        }
    };
    
  3. 收获

    • 这道题看起来不难,但是思考了很久,感觉自己还是没掌握背包问题。

解法二:空间压缩

  1. 思路

    • 「0-1背包问题」常规优化:「状态数组」从二维降到一维,减少空间复杂度。
    • 在「填表格」的时候,当前行总是参考了它上面一行「头顶上」那个位置和「左上角」某个位置的值。因此,可以只开一个一维数组,从后向前依次填表即可。
    • 「从后向前」写的过程中,一旦nums[i] <=j 不满足,可以马上退出当前循环,因为后面的j的值肯定越来越小,没有必要继续做判断,直接进入外层循环的下一层。相当于也是一个剪枝,这一点是「从前向后」填表所不具备的。
  2. 代码

    class Solution {
    public:
        bool canPartition(vector<int>& nums) {
            int n = nums.size();
            int sum = accumulate(nums.begin(), nums.end(), 0);
            // 特判:如果sum为奇数 则不符合要求
            if(sum % 2) return false;
            int mid = sum / 2;
            // dp[0][0] = false : 因为数组中不含0 因此元素和不可能为0
            vector<bool> dp(mid + 1, false);
            // 第一个数只能让容积为它自己的背包装满
            if(nums[0] <= mid){
                dp[nums[0]] = true;
            }
            for(int i=1; i<n; ++i){
                for(int j=mid; j>=nums[i]; --j){
                    if(j == nums[i])    dp[j] = true;
                    else if(j > nums[i]){
                        dp[j] = dp[j - nums[i]] || dp[j];
                    }
                }
            }
            return dp[mid];
        }
    };
    
  3. 收获

    • 在已经搞懂这道题的情况下,空间优化就容易很多。

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

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

相关文章

【CAN总线】CAN驱动程序分析

文章目录 一.CAN介绍二.CAN的特点二.CAN的错误检测三.OSI七层模型 一.CAN介绍 CAN具有很高的可靠性&#xff0c;广泛应用于&#xff1a;汽车电子&#xff0c;工业自动化&#xff0c;船舶&#xff0c;医疗设备&#xff0c;工业设备等方面。 当只有2个设备,简单通信,可以看成US…

【GoodERP专题】第一章 GoodERP应用专题之good_expense 费用报销 的使用

文章目录 一、模块设计二、模块1.主数据2.费用申请单3.借款单【付款】4.费用报销单【挂账/付款】5.出差申请单6.出差借款单【付款】7.差旅费报销单【挂账/付款】 总结 一、模块设计 费用报销模块是基于GoodERP框架设计的&#xff0c;该模块是为了解决企业内外费用相关报销任务处…

设计模式:结构型模式 - 装饰者模式

文章目录 1.概述2.结构3.案例4.使用场景5.JDK源码解析6.代理和装饰者的区别 1.概述 我们先来看一个快餐店的例子。 快餐店有炒面、炒饭这些快餐&#xff0c;可以额外附加鸡蛋、火腿、培根这些配菜&#xff0c;当然加配菜需要额外加钱&#xff0c;每个配菜的价钱通常不太一样&…

Tars-Cpp 协程实现分析

作者&#xff1a;vivo 互联网服务器团队- Ye Feng 本文介绍了协程的概念&#xff0c;并讨论了 Tars Cpp 协程的实现原理和源码分析。 一、前言 Tars 是 Linux 基金会的开源项目&#xff08;THE TARS FOUNDATION PROJECTS GitHub&#xff09;&#xff0c;它是基于名字服务使用…

VMware安装

1.首先去官网下载vmware for windows 2.按以下步骤进行点击 1&#xff09; 2&#xff09; 3&#xff09; 4&#xff09; 5&#xff09;两个取消勾选 6&#xff09; 7&#xff09; 9&#xff09;会出现重新启动的窗口&#xff0c;重新启动就可以&#xff01;

z时代,汽车品牌如何玩转年轻化营销?

随着2.6亿Z世代成为消费主力军&#xff0c;越来越多的品牌意识到&#xff1a;抓住年轻消费者&#xff0c;就等于抓住了一个消费时代。但信息大爆炸的背景下&#xff0c;年轻人的关注阈值越来越高。如何在消费新浪潮下&#xff0c;通过营销打通圈层壁垒&#xff0c;刷新Z世代的品…

浏览器页面操作——实时监控网页变化,读取网页内容

浏览器页面操作功能介绍 浏览器页面操作是集简云的一款免费内置应用&#xff0c;它可以定时监控网页变化&#xff0c;精准捕捉所需信息。一键设置指定网页与元素&#xff0c;全自动监测并即时推送通知&#xff0c;助您在第一时间了解网页最新情况&#xff0c;让您更高效便捷地…

搞懂API,创建供外部系统更新数据 API 的最佳方法

在创建一个供外部系统更新本系统数据的 API 时&#xff0c;需要考虑以下几个方面&#xff1a; 身份认证和安全性&#xff1a;首先需要确保 API 能够安全地接收外部系统发送的请求&#xff0c;可以使用身份认证和加密等方式保护 API 的安全性&#xff0c;避免非法和恶意请求。 …

4年的测试工程师,你遇到过自身瓶颈期吗?又是怎样度过的?

从毕业到现在已经快4年啦&#xff0c;一直软件测试行业混迹。我不是牛人&#xff0c;但是自我感觉还算是个合格的测试工程师&#xff0c;有必要写下自己将近4年来的经历&#xff0c;给自我以提示&#xff0c;给刚入行的朋友提供点参考。 貌似这一点适应的行业最广&#xff0c;…

如何雇佣一名全民开发者?

注&#xff1a;全民开发的英文是Citizen Development&#xff0c;由咨询公司Gartner在2010年提出的概念&#xff0c;指非专业开发人员使用低代码或无代码平台创建应用程序&#xff0c;无需IT部门的支持&#xff0c;旨在提高生产力并降低开发成本。 国内普遍将Citizen Developme…

Node服务端开发 【什么是Node】

文章目录 &#x1f31f;前言&#x1f31f;Node.js&#x1f31f;特性&#xff1a;&#x1f31f;1. 单线程&#x1f31f;2.异步IO&#x1f31f;前端中的异步&#x1f31f;Node中的异步 &#x1f31f;3.跨平台&#x1f31f;4.运行速度快 &#x1f31f; 劣势&#xff1a;&#x1f3…

7.java程序员必知必会类库之数据库连接池

前言 在java中&#xff0c;“池”化的设计思想随处可见&#xff0c;池化的最终目的是为了对象复用&#xff0c;降低系统创建、销毁对象的成本&#xff0c;提升资源的可管理性。 尤其是一些大对象&#xff0c;创建销毁比较消耗资源的对象&#xff0c;池化可以极大提高效率&…

EMQX vs Mosquitto | 2023 MQTT Broker 对比

引言 物联网开发者需要为自己的物联网项目选择合适的 MQTT 消息产品或服务&#xff0c;从而构建可靠高效的基础数据层&#xff0c;保障上层物联网业务。目前市面上有很多开源的 MQTT 产品&#xff0c;在性能功能等方面各有优点。本文将选取目前最为流行的两个开源 MQTT Broker…

最新!芯片行业有哪些知名企业?

01、芯片设计 芯片设计是产业链中重要的一环&#xff0c;影响后续芯片产品的功能、性能和成本&#xff0c;对研发实力要求较高。根据不同的下游应用&#xff0c;可分为四类&#xff1a; &#xff08;一&#xff09;集成电路&#xff1a;存储器、逻辑芯片&#xff08;CPU、GPU&…

进击的 Java !

编者按&#xff1a;近几年&#xff0c;随着云原生时代的到来&#xff0c;Java 遭受了诸多质疑。国际形势和行业格局的变化&#xff0c;大家一定充分感受到了云原生这个话题的热度&#xff0c;难道 Java 真的已过巅峰时期&#xff0c;要走向末路了吗&#xff1f;龙蜥社区 Java 语…

【Auto-GPT】会自主完成任务的 AI!安整的安装&使用教学

ChatGPT 需要我们不停的输入指令,引导 AI 的回答方向才能得到期待的结果;而 Auto-GPT 之所以爆红,就是因为他能够“自我反思”,只要给他任务,他就会不停地自问自答,不需要人为插手。 听起来是不是棒呆了?就让笔者透过这篇文章带大家了解如何安装 Auto-GPT,以及如何使用…

深入 Pinia:从代码出发探索 Vue 状态管理的奥秘

目录 一、 &#x1f3de;️创建源码分析环境1. 创建一个 vue 项目2. Pinia 源码入口3. 复制 Pinia 源码 & 在 main.ts 中初始化 Pinia 插件4. 添加必要仓库依赖5. 添加必要环境变量6. 环境测试 二、&#x1f9d0;源码分析&#xff08;1&#xff09;——执行流程三、&#x…

图像修复(Image Restoration)前沿

背景与现状 图像修复是一个长期存在的低层次视觉问题&#xff0c;旨在从损坏的输入图像中获取高质量图像&#xff0c;例如去模糊、去噪、去雾、去雨以及超分辨等。 L D ( H ) γ \mathbf{L} \mathbf{D}(\mathbf{H}) \gamma LD(H)γ 其中&#xff0c;L是低质量图像&#x…

电脑突然变成绿屏错误代码无法使用怎么办?

电脑突然变成绿屏错误代码无法使用怎么办&#xff1f;有用户使用电脑的时候&#xff0c;电脑桌面变成了绿屏的显示&#xff0c;所有的操作无法继续进行。遇到这个问题要怎么去进行解决呢&#xff1f;来看看详细的解决方法教学吧。 准备工作&#xff1a; 1、U盘一个&#xff08;…

Unity打包google play最新要求的aab文件的方法

很久不搞打包了&#xff0c;没想到google又整出新的花活了&#xff0c;apk变成了aab&#xff0c;这里分享一下。 首先有几个网址很重要&#xff0c;这里说一下&#xff1a; GitHub - google/play-unity-plugins: The Google Play Plugins for Unity provide C# APIs for acce…