474. 一和零--动态规划
Posted hequnwang10
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了474. 一和零--动态规划相关的知识,希望对你有一定的参考价值。
一、题目描述
给你一个二进制字符串数组 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 。
二、解题
动态规划
strs 数组里的元素就是物品,每个物品都是一个。m 和 n相当于是一个背包,两个维度的背包。
动态规划的步骤:
- 确定dp数组以及下标含义:
dp[i][j]:最多有i个0和j个1的strs的最大子集的大小为dp[i][j]; - 递推公式:
dp[i][j] 可以由前一个strs里的字符串推导出来,strs里的字符串有zero个0,one个1。dp[i][j] 就可以是 dp[i - zero][j - one] + 1。在遍历的过程中,取dp[i][j]的最大值。
递推公式:dp[i][j] = max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1); - dp数组如何初始化:
物品价值不会是负数,初始为0; - 确定遍历顺序
class Solution
public int findMaxForm(String[] strs, int m, int n)
if(strs == null || strs.length == 0)
return 0;
int[][] dp = new int[m+1][n+1];
for(String str : strs)
int ones = 0,zeros = 0;
for(char c : str.toCharArray())
if(c == '0')
zeros++;
else
ones++;
for(int i = m;i>=zeros;i--)
for(int j =n;j>=ones;j--)
dp[i][j] = Math.max(dp[i][j],dp[i-zeros][j-ones]+1);
return dp[m][n];
步骤分解
class Solution
public int findMaxForm(String[] strs, int m, int n)
if(strs == null || strs.length == 0)
return 0;
int[][] dp = new int[m+1][n+1];
for(String str : strs)
int ones = 0,zeros = 0;
for(char c : str.toCharArray())
if(c == '0')
zeros++;
else
ones++;
for(int i = m;i>=zeros;i--)
for(int j =n;j>=ones;j--)
System.out.println("i:"+i+"->j:"+j);
System.out.println("pre:"+"dp["+i+"]["+j+"]->"+dp[i][j]+"->"+"dp["+(i-zeros)+"]["+(j-ones)+"]->"+dp[i-zeros][j-ones]);
dp[i][j] = Math.max(dp[i][j],dp[i-zeros][j-ones]+1);
System.out.println("cur:"+"dp["+i+"]["+j+"]->"+dp[i][j]+"->"+"dp["+(i-zeros)+"]["+(j-ones)+"]->"+dp[i-zeros][j-ones]);
return dp[m][n];
i:1->j:1
pre:dp[1][1]->0->dp[0][0]->0
cur:dp[1][1]->1->dp[0][0]->0
i:1->j:1
pre:dp[1][1]->1->dp[0][1]->0
cur:dp[1][1]->1->dp[0][1]->0
i:1->j:0
pre:dp[1][0]->0->dp[0][0]->0
cur:dp[1][0]->1->dp[0][0]->0
i:1->j:1
pre:dp[1][1]->1->dp[1][0]->1
cur:dp[1][1]->2->dp[1][0]->1
i:0->j:1
pre:dp[0][1]->0->dp[0][0]->0
cur:dp[0][1]->1->dp[0][0]->0
以上是关于474. 一和零--动态规划的主要内容,如果未能解决你的问题,请参考以下文章
Leetcode之动态规划(DP)专题-474. 一和零(Ones and Zeroes)
LeetCode 474 一和零[二进制 动态规划] HERODING的LeetCode之路