LeetCode474. 一和零

474. 一和零

文章目录

    • [474. 一和零](https://leetcode.cn/problems/ones-and-zeroes/)
      • 一、题目
      • 二、题解
        • 方法一:01背包
        • 方法二:01背包三维数组


一、题目

给你一个二进制字符串数组 strs 和两个整数 mn

请你找出并返回 strs 的最大子集的长度,该子集中 最多m0n1

如果 x 的所有元素也是 y 的元素,集合 x 是集合 y子集

示例 1:

输入:strs = ["10", "0001", "111001", "1", "0"], m = 5, n = 3
输出:4
解释:最多有 5 个 0 和 3 个 1 的最大子集是 {"10","0001","1","0"} ,因此答案是 4 。
其他满足题意但较小的子集包括 {"0001","1"} 和 {"10","1","0"} 。{"111001"} 不满足题意,因为它含 4 个 1 ,大于 n 的值 3 。

示例 2:

输入:strs = ["10", "0", "1"], m = 1, n = 1
输出:2
解释:最大的子集是 {"0", "1"} ,所以答案是 2 。

提示:

  • 1 <= strs.length <= 600
  • 1 <= strs[i].length <= 100
  • strs[i] 仅由 '0''1' 组成
  • 1 <= m, n <= 100

二、题解

方法一:01背包

我们将这个问题与01背包问题联系起来:

  • 物品:字符串数组strs中的每个字符串可以看作一个物品。
  • 重量:每个字符串有两个重量,分别是0的数量(zeroNum)和1的数量(oneNum)。
  • 价值:每个字符串的价值都是1,因为我们的目标是找到最大子集的长度,价值即为长度。

问题的限制条件如下:

  • 背包容量1:最多有m个0。
  • 背包容量2:最多有n个1。

思考过程

  1. 首先,我们需要找到一个动态规划的状态表示。题目要求找出一个最大子集,这个子集中最多有m个0和n个1。我们可以用一个二维数组dp来表示状态,其中dp[i][j]表示在限制条件下最多可以包含i个0和j个1的子集的最大长度。

  2. 接下来,我们需要找到状态转移方程,也就是如何从一个状态转移到下一个状态。对于每个字符串strs[i],我们需要考虑两种情况:

    • 如果选择不包含这个字符串,那么dp[i][j] = dp[i-1][j],表示不使用这个字符串,保持前一个状态的值。
    • 如果选择包含这个字符串,我们需要减去这个字符串中0和1的数量(zeroNum和oneNum),然后更新dp[i][j]。具体来说,dp[i][j] = max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1)。这表示如果选择包含这个字符串,我们可以在前一个状态的基础上加1,但是要确保不超过限制条件;或者说如果原状的个数更多,那么维持原状。
  3. 最后,我们需要遍历所有的字符串并填充dp数组,然后返回dp[m][n]作为最终答案。

代码

class Solution {
public://找到字符串中0和1数量void countNum(string str, int &a, int &b){for(int i = 0; i < str.size(); i++){if(str[i] == '1'){b++;}else{a++;}}}int findMaxForm(vector<string>& strs, int m, int n) {//dp[i][j]代表i个0和j个1情况下最多子集数量vector<vector<int>> dp(m+1,vector<int>(n+1, 0));for(string str: strs){int oneNum = 0;int zeroNum = 0;countNum(str, zeroNum, oneNum);for(int i = m; i >= zeroNum; i--){for(int j = n; j >= oneNum; j--){dp[i][j] = max(dp[i][j],dp[i-zeroNum][j-oneNum]+1);}}}return dp[m][n];}
};

方法二:01背包三维数组

其他思路与上面差不多,就先忽略,下面是一些细节性的部分:

初始化

首先,对于第一个字符串 strs[0],我们需要计算其包含的0和1的数量,分别记为 zero_pone_p。接着,我们初始化 dp[0][i][j] 数组,其中 i 表示可用的0的数量, j 表示可用的1的数量。初始化规则是:

  • 如果 zero_p 不超过可用的0数量 i,并且 one_p 不超过可用的1数量 j,则 dp[0][i][j] 被设为1,表示可以选择该字符串。

这一步确保了在考虑第一个字符串时,我们只考虑了可行的情况。

填写 dp 数组

接下来,我们遍历字符串数组 strs,从第二个字符串开始(因为第一个字符串已经处理过了),计算每个字符串中0和1的数量,分别为 zeroNumoneNum

然后,我们使用嵌套的循环遍历可用的0和1的数量(jk),并填充 dp 数组:

  • 如果 j 小于 zeroNum 或者 k 小于 oneNum,则说明当前字符串不能选择,因此 dp[i][j][k] 等于上一个状态 dp[i-1][j][k]

  • 否则,我们有两个选择:不选择当前字符串(继承上一个状态)或选择当前字符串(当前状态等于上一个状态减去当前字符串的0和1数量再加1)。我们选择这两者中的较大值。

最终,dp[strs.size()-1][m][n] 包含了所有字符串的最优解,表示在限制条件下可以获得的最大子集长度。

class Solution {
public:void countNum(string str, int &a, int &b){for(int i = 0; i < str.size(); i++){if(str[i] == '1'){b++;}else{a++;}}}int findMaxForm(vector<string>& strs, int m, int n) {//dp[i][j][k]代表在0到i个元素中,j个0和k个1的最大子集vector<vector<vector<int>>> dp(strs.size(),vector<vector<int>>(m+1,vector<int>(n+1,0)));//初始化int one_p = 0;int zero_p = 0;countNum(strs[0],one_p,zero_p);for(int i = 0; i <= m; i++){for(int j = 0; j <= n; j++){if(one_p <= i && zero_p <= j){dp[0][i][j] = 1;}}}//填写dp数组for(int i = 1; i < strs.size(); i++){int oneNum = 0;int zeroNum = 0;countNum(strs[i], zeroNum, oneNum);for(int j = 0; j <= m; j++){for(int k = 0; k <= n; k++){if(j < zeroNum || k < oneNum){dp[i][j][k] = dp[i-1][j][k];}else{dp[i][j][k] = max(dp[i-1][j][k],dp[i-1][j-zeroNum][k-oneNum]+1);}}}}return dp[strs.size()-1][m][n];}
};

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

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

相关文章

第 362 场 LeetCode 周赛题解

A 与车相交的点 数据范围小直接暴力枚举 class Solution { public:int numberOfPoints(vector <vector<int>> &nums) {unordered_set<int> vis;for (auto &p: nums)for (int i p[0]; i < p[1]; i)vis.insert(i);return vis.size();} };B 判断能否…

DC/DC开关电源学习笔记(六)开关电源电路集成及封装工艺

(六)开关电源电路集成及封装工艺 1.集成工艺2.模块化3.新方向开关电源电路集成及封装工艺涉及到将电源电路的各个组成部分集成在一个芯片中,并对芯片进行封装的工艺过程。 1.集成工艺 在集成电路设计中,通常会将开关电源的主要功能模块如开关管、变压器、滤波电容、电感等…

普中 51 单片机点亮LED灯

普中 51 单片机 &#xff08;STC89C52RC&#xff09; LED / IO 将LED1进行闪烁操作 为啥要进行延时操作&#xff1f;依据人的肉眼余晖效应&#xff0c; 延时时间不能太短&#xff0c;否则就无法观察到 LED 闪烁 #include "reg52.h" typedef unsigned int u16; //对…

React中父子组件参数传递讲解

文章目录 结合案例&#xff1a;github搜索案例1.父容器代码2.搜索Search子模块代码3.展示Lisi子模块代码 父子参数传递分析1.子(Search)传父(App)2.父(App)传子(List) 结合案例&#xff1a;github搜索案例 案例结果展示如下图 1.父容器代码 import React, { Component } fr…

自己封装的reduce、map、foreach、filter、bind等方法

自己封装一些方法 reduce 方法map 方法forEach方法filter方法的封装bind方法的封装 reduce 方法 在这个自定义的 reduce 方法中&#xff0c;我们遵循了原生 reduce 方法的工作原理。我们接受三个参数&#xff1a;数组 arr&#xff0c;回调函数 callback 和初始值 initialValue…

【GO语言基础】前言

系列文章目录 【Go语言学习】ide安装与配置 【GO语言基础】前言 【GO语言基础】变量常量 【GO语言基础】数据类型 文章目录 系列文章目录一、基础知识包和函数函数声明语法简洁性 括号成对出现GO常用DOS命令命名规则项目目录结构注释 总结 一、基础知识 包和函数 //声明本代…

Python中使用item()方法遍历字典的例子

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 这篇文章主要介绍了Python中使用item()方法遍历字典的例子, for…in这种是Python中最常用的遍历字典的方法了,需要的朋友可以参考下 Python字典的遍历方法有好几种&#xff0c;其中一种是for…in&#xff0c;这个我就…

记录docker 部署nessus

1、开启容器 docker run -itd --nameramisec_nessus -p 8834:8834 ramisec/nessus 2、登录 &#xff1a;注意是https https://ip8843 3、修改admin密码 #进入容器 docker exec -it ramisec_nessus /bin/bash#列出用户名 /opt/nessus/sbin/nessuscli lsuser#修改密码&a…

Swift使用编解码库Codable

Codable 是 Swift 引入的全新的编解码库&#xff0c;使开发者更方便的解析JSON 或 plist 文件。支持枚举、结构体和类。 Codable协议定义 Codable代表一个同时符合 Decodable 和 Encodable 协议的类型&#xff0c;即可解码且可编码的类型。 typealias Codable Decodable &a…

python模块之 aiomysql 异步mysql

mysql安装教程 mysql语法大全 python 模块pymysql模块&#xff0c;连接mysql数据库 一、介绍 aiomysql 是一个基于 asyncio 的异步 MySQL 客户端库&#xff0c;用于在 Python 中与 MySQL 数据库进行交互。它提供了异步的数据库连接和查询操作&#xff0c;适用于异步编程环境 …

计算机网络(一):基础篇

文章目录 1. TCP/IP网络模型有哪几层并做简要介绍&#xff1f;2. 键入网址到网页显示&#xff0c;期间发生了什么&#xff1f;3. 介绍一下域名解析的工作流程&#xff1f;4. MAC发送方和接收方如何确认&#xff1f;5. 路由器和交换机的区别&#xff1f;6. Linux系统是如何收发网…

sqlserver union和union all 的区别

1.首先在数据库编辑1-40数字&#xff1b; 2.查询Num<30的数据&#xff0c;查询Num>20 and Num<40的数据&#xff0c;使用union all合并&#xff1b; 发现30-20的数字重复了&#xff0c;可见union all 不去重&#xff1b; 3.查询Num<30的数据&#xff0c;查询Num…

表的内连接和外连接

表的连接是SQL中的一种操作&#xff0c;用于将两个或多个表中的数据按照某个条件进行关联。 内连接 使用内连接将两个表(Table1 和 Table2)进行连接&#xff1a; select * from Table1 inner join Table2 on Table1.id Table2.id;举例&#xff1a; -- 用普通的写法 select…

idea右边找不到maven窗口(Idea_最右侧常用栏中没有Maven选项)

方案一&#xff1a; 首先idea自带了maven控件&#xff0c;不像Eclipse还需要下载控件&#xff0c;如果你以前有maven在右边&#xff0c;出于某种原因&#xff0c;消失找不到 了&#xff0c;你可以试试我写的方法。 方法1.你点击一下你idea界面最左下角的那个小框&#xff0c…

Promise 解决 Vue 中父子组件的加载问题!

前言 关于Promie我这里就不多解释了&#xff0c;不懂得可以看看官方文档。下面文章重点介绍项目中遇到的问题解决方法。 需求 组件b初始化某个用到的库&#xff0c;只有在初始化完成后才能调用其API&#xff0c;不然会报错。a页面负责调用。 // a.vue <template><d…

动态表单设计

动态表单设计 背景方案讨论基于上面分析&#xff0c;对比调研&#xff0c;自定义动态表单数据模型表单详解&#xff08;一&#xff09; 表单模板&#xff1a;jim_dynamic_form&#xff08;二&#xff09;表单数据类型&#xff1a;jim_form_data_type&#xff08;三&#xff09;…

element ui el-table分页多选功能

selection-change&#xff1a;当选择项发生变化时会触发该事件&#xff08;当分页切换时&#xff0c;选中的数据都会自动清空&#xff09; 一、在el-table中添加 :row-key“id” <el-table :data"tableData" border style"width: 95%" selection-change…

【Linux】编辑器 vim

1、vim的基本概念 vi/vim【一款文本编辑器】vim【一款多模式编辑器】vi/vim 的区别简单点来说&#xff0c;它们都是多模式编辑器&#xff0c;不同的是 vim 是 vi 的升级版本&#xff0c;它不仅兼容vi的所有指令&#xff0c;而且还有一些新的特性在里面。例如语法加亮&#xff0…

redis-win10安装和解决清缓存报错“Error: Protocol error, got “H“ as reply type byte”

win10安装 https://github.com/microsoftarchive/redis/releases 下载最新的zip&#xff0c;解压&#xff0c;把路径加到Path里&#xff0c;每次直接在cmd里 redis-server.exeError: Protocol error, got “H” as reply type byte 这个报错是因为我端口写错了。。无语 D:…

分享一个python实验室设备预约管理系统 实验室设备维修系统源码 lw 调试

&#x1f495;&#x1f495;作者&#xff1a;计算机源码社 &#x1f495;&#x1f495;个人简介&#xff1a;本人七年开发经验&#xff0c;擅长Java、Python、PHP、.NET、微信小程序、爬虫、大数据等&#xff0c;大家有这一块的问题可以一起交流&#xff01; &#x1f495;&…