当前位置:网站首页>代码随想录笔记_动态规划_474一和零
代码随想录笔记_动态规划_474一和零
2022-08-06 19:44:00 【Erik_Won】
代码随想录二刷笔记记录
LC474.一和零
题目
01背包
给你一个二进制字符串数组 strs 和两个整数 m 和 n 。
请你找出并返回 strs 的最大子集的长度,该子集中 最多 有 m 个 0 和 n 个 1 。
如果 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
思路分析
思路:
strs数组中的元素看作物品,m和n相当于是一个二维背包
选取物品时,不仅要考虑 m(1的数量) 还要考虑 n (0的数量)
动态规划五部曲
1.确定dp数组及其下标的含义
dp[i][j]: 由 i 个 0 和 j 个 1 组成的字符串数组strs最大子集的大小
2.确定递推公式
由题可知,子集的 0 和 1 的数量 (zeroNum,oneNum) 不能超过限定的数量 m,n
回顾 01背包 递推公式
//二维
dp[i][j] = Max(dp[i][j],dp[i][j - weight[i]] + value[i])
//一维
dp[j] = Max(dp[j],dp[j - weight[i]] + value[i])
本题的当前状态,需要从前一个状态推导而来
dp[i][j] 需要由前一个 strs 数组中的字符串 s 所推导而来。
推导时需要判断 s 的 zeroNum 和 oneNum 是否超过了限制的m和n
因此:
i + zeroNum <= m , j + oneNum <= n
推导过程取最大值,即最大子集,则有递推公式
dp[i][j] = Max(dp[i][j],dp[i - zeroNum][j - oneNum] + 1)
可以将 [i - zeroNum][j - oneNum] 视为减去物品的重量 weight[i]
字符串的个数 + 1 视为 value[i]
3.初始化
因为物品的价值。即strs的字符串数量不可能为负数,因此初始化为 0 即可。
4.遍历顺序
//1.先遍历字符串,统计当前字符串的 zeroNum 和 oneNum
for(String str : strs){
int oneNum;
int zeroNum;
for(char c : str){
zeroNum = 0;
oneNum = 0;
if('0' == c){
zeroNum++;
}else{
oneNum++;
}
}
//2.后遍历01背包
//遍历二维背包的容量
//每个字符串只放一次,不重放,逆序遍历
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);
}
}
}
5.推演分析
输入:strs = [“10”, “0001”, “111001”, “1”, “0”], m = 3, n = 3 输出:3
注意:背包遍历顺序是逆序遍历,因此这里应该为倒推,从右下角向左上角推导。
| 物品str/容量ij | 0 | 1 | 2 | 3 |
|---|---|---|---|---|
| 0 | 0 | 0->1 | 0->1 | 0->1 |
| 1 | 0->1 | 0->1->2 | 0->1->2 | 0->1->2 |
| 2 | 0->1 | 0->1->2 | 0->1->2->3 | 0->1->2->3 |
| 3 | 0->1 | 0->1->2 | 0->1->2->3 | 0->1->2->3 |
代码实现
完整代码实现
public int findMaxForm(String[] strs, int m, int n) {
//m:0的个数,n:1的个数
if(0 == strs.length) return 0;
//初始化
int[][] dp = new int[m+1][n+1];
int zeroNum;
int oneNum;
//遍历顺序
//遍历物品str
for(String str: strs){
zeroNum = 0;
oneNum = 0;
for(char c: str.toCharArray()){
if('0' == c){
zeroNum++;
}else{
oneNum++;
}
}
//遍历二维背包,逆序遍历
for(int i = m; i >= zeroNum;i--){
for(int j = n; j >= oneNum;j--){
dp[i][j] = Math.max(dp[i][j],dp[i - zeroNum][j - oneNum] + 1);
}
}
}
return dp[m][n];
}
小结
本题考察二维01背包,同样是考察 01 背包,对我们把题目的条件,转化为物品,背包容量,有一定的难度。需要找到其中的关系,将字符串数组中的元素 s 看作物品,将限制条件 m 和 n 转化为背包容量。
边栏推荐
猜你喜欢

Open3D Airborne Point Cloud Powerline Extraction

Pagoda measurement-PHP web version online customer service system source code

How to Give Your WordPress Blog Site a Beautiful Font

索引的设计原则

PromQL query monitoring data

ECCV2022|你没见过的《老友记》镜头,AI给补出来了

UNet语义分割网络

我们来聊聊锁升级吧

大多数人都会答错的一题:如果要存 IP 地址,用什么数据类型比较好?

How from form to get default value
随机推荐
Pytest学习-读取YAML文件
#yyds dry goods inventory# Interview must brush TOP101: determine whether a linked list is a palindrome structure
[LeetCode]1403. 非递增顺序的最小子序列
ansible各个模块详解2
A question that most people get wrong: If I want to store IP addresses, what data type is better?
The correct way to open ESLint plugin rule writing
牛客面试刷题
几种 SAP ABAP OData 服务的性能评估和测试工具介绍试读版
The meaning, tools, categories and differences of version control
File download and read of file operation
站在数字经济浪尖:360视觉云探路中小微企业数智转型
路由router
STPM leverages teacher-student networks for unsupervised anomaly detection
14. 几种 SAP ABAP OData 服务的性能评估和测试工具介绍
如何给WordPress博客网站换个漂亮的字体
LeetCode Daily Question (2007. Find Original Array From Doubled Array)
ceph-ansible5.0部署文档
Redis 的网络框架是实现了 Reactor 模型吗?
Stream streams are grouped by multiple fields
【无标题】BOOT SERVICES函数实现原型: