LeetCode-416. 分割等和子集

news2024/12/27 1:09:31

目录

    • 题目分析
    • 回溯法
    • 动态规划
    • 动态规划(压缩)

题目来源
416. 分割等和子集

题目分析

这道题目是要找是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。
那么只要找到集合里能够出现 sum / 2 的子集总和,就算是可以分割成两个相同元素和子集了。

回溯法

这道题和39. 组合总和非常类似(可以去做一下)
LeetCode-39. 组合总和

class Solution {
    boolean res;
    public boolean canPartition(int[] nums) {
        int sum = 0;
        for(int i = 0;i<nums.length;i++){
            sum += nums[i];
        }
        //如果为奇数,肯定就没有两个相等的子集了
        if(sum % 2 == 1){
            return false;
        }
        //查找目标target的子集和
        int target = sum / 2;
        backTracking(nums,0,0,target);
        return res;
    }

    //startIndex为了数组不选取重复元素,sum为加起来的总和,target目标数
    private void backTracking(int[] nums,int startIndex,int sum,int target){
        //如果sum>target就没必要进行计算了
        if(sum > target){
            return;
        }
        //如果等于,直接将res设置为为true,相当于是相同子集了
        if(sum == target){
            res = true;
            return;
        }
        for(int i = startIndex;i<nums.length;i++){
            sum+=nums[i];
            backTracking(nums,i+1,sum,target);
            sum-=nums[i];  //回溯
        }
    }
}

这道题使用回溯算法不行(超时),那么就要用动态规划了
在这里插入图片描述

动态规划

背包问题,大家都知道,有N件物品和一个最多能背重量为W 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。
背包问题有多种背包方式,常见的有:01背包、完全背包、多重背包、分组背包和混合背包等等。
要注意题目描述中商品是不是可以重复放入。
即一个商品如果可以重复多次放入是完全背包,而只能放入一次是01背包,写法还是不一样的。
要明确本题中我们要使用的是01背包,因为元素我们只能用一次。
回归主题:首先,本题要求集合里能否出现总和为 sum / 2 的子集。
那么来一一对应一下本题,看看背包问题如何来解决。
只有确定了如下四点,才能把01背包问题套到本题上来。

  • 背包的体积为sum / 2
  • 背包要放入的商品(集合里的元素)重量为 元素的数值,价值也为元素的数值
  • 背包如果正好装满,说明找到了总和为 sum / 2 的子集。
  • 背包中每一个元素是不可重复放入。

理解了0-1背包问题,直接搬照着公式就可以写出
https://donglin.blog.csdn.net/article/details/129412502

class Solution {
    public boolean canPartition(int[] nums) {
        if(nums == null){
            return false;
        }
        int sum = 0;
        for(int num : nums){
            sum += num;
        }
        if(sum % 2 == 1){
            return false;
        }
        int target = sum / 2;
        int[][] dp = new int[nums.length][target+1];
        for(int j=target;j>=nums[0];j--){
            dp[0][j] = nums[0];
        }
        for(int i = 1;i<nums.length;i++){
            for(int j = 1;j<=target;j++){
                if(j<nums[i]){
                    dp[i][j] = dp[i-1][j];
                }else{
                    dp[i][j] = Math.max(dp[i-1][j],dp[i-1][j-nums[i]]+nums[i]);
                }
            }
        }
        return dp[nums.length-1][target]==target;
    }
}

在这里插入图片描述

动态规划(压缩)

动规五部曲分析如下:

  • 1.确定dp数组以及下标的含义

01背包中,dp[j] 表示: 容量为j的背包,所背的物品价值最大可以为dp[j]。
本题中每一个元素的数值既是重量,也是价值。
套到本题,dp[j]表示 背包总容量(所能装的总重量)是j,放进物品后,背的最大重量为dp[j]。
那么如果背包容量为target, dp[target]就是装满 背包之后的重量,所以 当 dp[target] == target 的时候,背包就装满了。

  • 2.确定递推公式

如果不清楚0-1背包问题的一维数组,可以看这篇
https://donglin.blog.csdn.net/article/details/129437136
01背包的递推公式为:dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
相当于背包里放入数值,那么物品i的重量是nums[i],其价值也是nums[i]。
所以递推公式:dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]);

  • 3.dp数组如何初始化

在01背包,一维dp如何初始化,已经讲过,
从dp[j]的定义来看,首先dp[0]一定是0。

  • 4.确定遍历顺序

如果使用一维dp数组,物品遍历的for循环放在外层,遍历背包的for循环放在内层,且内层for循环倒序遍历!

        for(int i = 0;i<nums.length;i++){
            for(int j = target;j>=nums[i];j--){
                dp[j] = Math.max(dp[j],dp[j-nums[i]]+nums[i]);
            }
        }
  • 5.举例推导dp数组

在这里插入图片描述

完整代码

class Solution {
    public boolean canPartition(int[] nums) {
        if(nums == null){
            return false;
        }
        int sum = 0;
        for(int num : nums){
            sum += num;
        }
        if(sum % 2 == 1){
            return false;
        }
        int target = sum / 2;
        int[] dp = new int[target+1];
        for(int i = 0;i<nums.length;i++){
            for(int j = target;j>=nums[i];j--){
                //物品 i 的重量是 nums[i],其价值也是 nums[i]
                dp[j] = Math.max(dp[j],dp[j-nums[i]]+nums[i]);
            }
        }
        return dp[target] == target;
    }
}

在这里插入图片描述

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

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

相关文章

使用 ONLYOFFICE 宏借助 ChatGPT 生成文章

AI 技术在过去几年中得到了显著提升&#xff0c;同时也成为了我们日常生活中必不可少的一部分。现在&#xff0c;我们会将这种高科技功能纳入到文档撰写过程。在本文中&#xff0c;我们将展示如何构建一个宏来使用 ChatGPT API 生成文章。 关于 ChatGPT ChatGPT 是由 OpenAI 开…

html2canvas和jspdf导出pdf,每个页面模块占一页,在pdf中垂直居中显示

需求&#xff1a;html页面转换pdf&#xff0c;页面有多个模块&#xff0c;页面中有文本、echarts、表格等模块&#xff0c;一个模块占一页&#xff0c;因为模块高度不够&#xff0c;所以需要垂直居中 通过html2canvas和jspdf实现&#xff0c;html2canvas用于将页面元素生成canv…

以java编写员工管理系统(测试过 无问题)

一、系统结果的部分展示 二、题目以及相关要求 三、组成 1.该系统由 Employee 类 、commonEmployee类、Testemd类和managerEmployee类组成 2.Employee实现的代码 public class Employee {private String id;private String name;private String job;private int holiday…

弱监督参考图像分割:Learning From Box Annotations for Referring Image Segmentation论文阅读笔记

弱监督参考图像分割&#xff1a;Learning From Box Annotations for Referring Image Segmentation论文阅读笔记一、Abstract二、引言三、相关工作A、全监督参考图像分割B、基于 Box 的实例分割C、带有噪声标签的学习四、提出的方法A、概述B、伪标签生成目标轮廓预测Proposal 选…

exe打包工具:advanced installer介绍(一)

前言近年来&#xff0c;web服务逐渐走向云端部署浏览器化、去APP化&#xff0c;然而exe安装仍有着举足轻重的地位&#xff0c;其好处不言而喻&#xff0c;拿到exe安装包后&#xff0c;基本就可以傻瓜安装和操作了&#xff0c;十分便捷。业务场景通过各种IDE/QT/C#/Java等开发工…

项目的生命周期与成本、风险、变更的关系

成本与人力投入水平 项目成本的投入在初始阶段逐渐增加&#xff0c;在执行的中间阶段达到顶峰&#xff0c;在项目收尾阶段逐渐下降。成本的投入趋势如下图所示&#xff1a; 初始阶段&#xff1a;从人力成本来看&#xff0c;信息系统开发团队在前期制定项目管理章程及项目管理…

PCB焊盘设计基本原则

SMT的组装质量与PCB焊盘设计有直接的关系&#xff0c;焊盘的大小比例十分重要。如果PCB焊盘设计正确&#xff0c;贴装时少量的歪斜可以再次回流焊纠正(称为自定位或自校正效应)&#xff0c;相反&#xff0c;如果PCB焊盘设计不正确&#xff0c;即使贴装位置十分准确&#xff0c;…

图像金字塔,原理、实现及应用

什么是图像金字塔 图像金字塔是对图像的一种多尺度表达&#xff0c;将各个尺度的图像按照分辨率从小到大&#xff0c;依次从上到下排列&#xff0c;就会形成类似金字塔的结构&#xff0c;因此称为图像金字塔。 常见的图像金字塔有两类&#xff0c;一种是高斯金字塔&#xff0…

为什么越来越多的人开始学习大数据

因为根据国内的发展形势&#xff0c;大数据未来的发展前景会非常好&#xff0c;前景好需求高&#xff0c;自然会吸引越来越多的人进入大数据行业 我国市场环境处于急需大数据人才但人才不足的阶段&#xff0c;所以未来大数据领域会有很多的就业机遇。 2022年春季&#xff0c;…

camunda流程引擎基本使用(笔记)

文章目录一、camunda基础1.1 安装与部署流程引擎1.2 流程引擎结构1.3 流程引擎的基本使用1.3.1 创建一个BPMN Diagram1.3.2 实现一个外部工作者1.3.3 部署流程1.3.4 创建一个流程实例并消费1.3.5 向流程中添加用户任务1.3.6 添加网关1.3.7 业务规则二、Java 集成流程引擎2.1 为…

酷开科技大数据揭秘!酷开系统中的千屏千面究竟指的是什么?

互联网行业的快速发展&#xff0c;给我们带来了极大的便利。回顾整个互联网行业的发展历程&#xff0c;从PC时代到移动互联网时代&#xff0c;从移动互联网时代到物联网时代&#xff0c;现在又即将从物联网时代迈入人工智能时代。这些飞速发展的背后&#xff0c;其实是对数据利…

ICG-alkyne,吲哚菁绿-炔基结构式,实验室科研试剂,CAS号:1622335-41-4

ICG-alkyne,吲哚菁绿-炔基 中文名称&#xff1a;吲哚菁绿-炔基 CAS号&#xff1a;1622335-41-4 英文名称&#xff1a;ICG-alkyne 英文别名&#xff1a;ICG-alk 性状&#xff1a;绿色粉末 化学式&#xff1a;C48H53N3O4S 分子量&#xff1a;768.03 溶剂&#xff1a;溶于…

3BHE029110R0111 ABB

3BHE029110R0111 ABB变频器控制方式低压通用变频输出电压为380&#xff5e;650V&#xff0c;输出功率为0.75&#xff5e;400kW&#xff0c;工作频率为0&#xff5e;400Hz&#xff0c;它的主电路都采用交—直—交电路。其控制方式经历了以下四代。1U/fC的正弦脉宽调制&#xff0…

ggplot2的组图拓展包(1):patchwork(中篇)

专注系列化、高质量的R语言教程推文索引 | 联系小编 | 付费合集上篇和上篇续介绍了使用操作符进行组图的方法&#xff0c;这里默认读者已经能够理解各种操作符在本篇推文中的使用场景。本篇目录如下&#xff1a;0 示例图形6 plot_layout函数&#xff08;下&#xff09;6.1 guid…

CSS3-数据可视化

2D动画 - transform CSS3 transform属性允许你旋转&#xff0c;缩放&#xff0c;倾斜或平移给定元素。 Transform是形变的意思&#xff08;通常也叫变换&#xff09;&#xff0c;transformer就是变形金刚 常见的函数transform function有&#xff1a; 平移&#xff1a;transl…

实际开发中如何存储密码(md5加盐bcrypt)golang

文章目录简介加盐的加密方式md5 加盐方式bcrypt 方式简介 一般前端把用户密码发给服务端&#xff0c;服务端实际业务中如何存储密码呢&#xff0c;如何存储密码才能保证密码不被开发者获取或者被截取呢&#xff0c;保证密码的安全 加盐的加密方式 现在的企业开发大都采用这种…

凌恩生物文献分享|颠覆性的宏基因组新思路,速来get!

非人灵长类动物&#xff08;NHP&#xff09;是人类的近亲&#xff0c;为宿主-微生物互作的研究提供了一个很好的例子。近年来研究主要集中在野生灵长类动物的肠道微生物群&#xff0c;这将有助于了解灵长类及其肠道微生物群的进化&#xff0c;但仍然缺乏关于野生种群肠道微生物…

通用后台管理系统-前端搭建

一 背景 基于vuespringboot 搭建一套通用管理后台 主要包括用户管理模块、权限模块、菜单模块 二 环境信息 2.1 前端工具版本 2.1.1 npm 版本 PS D:\front> npm -v 8.5.0PS D:\front> npm config get registry https://registry.npm.taobao.org/ PS D:\front>2.1…

埋点tracker:前端埋点服务-技术要点梳理

一、背景埋点方案&#xff0c;前端涉及到哪些技术要点&#xff0c;本文做简单的梳理和总结。二、指纹追踪技术&#xff1a;识别到用户及设备浏览器&#xff1a;浏览器指纹_snowli的博客-CSDN博客三、用户设备信息&#xff08;navigator&#xff09;navigator.userAgent四、页面…

利用Mysql存储过程造百万级数据

1.准备工作&#xff08;1&#xff09;由于是使用存储过程&#xff0c;mysql从5.0版开始支持存储过程&#xff0c;那么需要mysql的版本在5.0或者以上。如何查看mysql的版本&#xff0c;使用下面sql语句查看&#xff1a;&#xff08;2&#xff09;创建两张表&#xff0c;表结构一…