474 Ones and Zeroes
474. Ones and Zeroes
1. Question
In the computer world, use restricted resource you have to generate maximum benefit is what we always want to pursue.
For now, suppose you are a dominator of m0s
and n1s
respectively. On the other hand, there is an array with strings consisting of only0s
and1s
.
Now your task is to find the maximum number of strings that you can form with givenm0s
andn1s
. Each0
and1
can be used at most once.
Note:
The given numbers of
0s
and1s
will both not exceed100
The size of given string array won't exceed
600
.
Example 1:
Input: Array = {"10", "0001", "111001", "1", "0"}, m = 5, n = 3
Output: 4
Explanation:
This are totally 4 strings can be formed by the using of 5 0s and 3 1s, which are “10,”0001”,”1”,”0”
Example 2:
Input: Array = {"10", "0", "1"}, m = 1, n = 1
Output: 2
Explanation:
You could form "10", but then you'd have nothing left. Better form "0" and "1".
2. Implementation
(1) DP
思路: 这题要我们用m个0和n个1,组成最多的string(每个string都由0或1组成)。这是很明显的0-1背包问题,是二维的0-1背包问题,可以直接用模板写
class Solution {
public int findMaxForm(String[] strs, int m, int n) {
if (strs == null || strs.length == 0 || m < 0 || n < 0) {
return 0;
}
// dp[i][j][k] means the max number of strings we can form with number of j 0s and k 1s for the first i strings in strs
int[][][] dp = new int[strs.length + 1][m + 1][n + 1];
int[] count = new int[2];
for (int i = 0; i <= strs.length; i++) {
// The first row is empty string, skip the first row
if (i == 0) continue;
count = countOnesAndZeroes(strs[i - 1]);
for (int j = 0; j <= m; j++) {
for (int k = 0; k <= n; k++) {
// When we have enough 1s and 0s to form the current string string strs[i - 1]
// Two strategies: Form it or skip it
if (count[0] <= j && count[1] <= k) {
dp[i][j][k] = Math.max(dp[i - 1][j][k], dp[i - 1][j - count[0]][k - count[1]] + 1);
}
// Do nothing
else {
dp[i][j][k] = dp[i - 1][j][k];
}
}
}
}
return dp[strs.length][m][n];
}
public int[] countOnesAndZeroes(String s) {
int[] count = new int[2];
for (char c : s.toCharArray()) {
++count[c - '0'];
}
return count;
}
}
(2) DP空间优化
class Solution {
public int findMaxForm(String[] strs, int m, int n) {
if (strs == null || strs.length == 0|| m < 0 || n < 0) {
return 0;
}
int[][] dp = new int[m + 1][n + 1];
int[] count = new int[2];
for (int i = 0; i < strs.length; i++) {
count = countOnesAndZeroes(strs[i]);
for (int j = m; j >= count[0]; j--) {
for (int k = n; k >= count[1]; k--) {
dp[j][k] = Math.max(dp[j][k], dp[j - count[0]][k - count[1]] + 1);
}
}
}
return dp[m][n];
}
public int[] countOnesAndZeroes(String s) {
int[] count = new int[2];
for (char c :s.toCharArray()) {
++count[c - '0'];
}
return count;
}
}
3. Time & Space Complexity
DP: 时间复杂度O(k * l * m * n), 空间复杂度O(kmn)
DP空间优化: 时间复杂度O(k * l * m * n), 空间复杂度O(mn)
Last updated
Was this helpful?