474. Ones and Zeroes 发表于 2022-01-24 DP12345678910111213141516171819202122232425262728293031323334class Solution { public int findMaxForm(String[] strs, int m, int n) { // 定义 dp[i][j][k] 为从前 i 个字符串中选择 dp[i][j][k] 个字符串组成的子集最多含有 m 个 0 和 n 个 1 int[][][] dp = new int[strs.length + 1][m + 1][n + 1]; for (int i = 1; i <= strs.length; i++) { int[] weight = getWeight(strs[i - 1]); int zeroCount = weight[0], oneCount = weight[1]; // 注意 j 和 k 要从 0 开始遍历,因为可能存在 0 个 0 或 0 个 1 for (int j = 0; j <= m; j++) { for (int k = 0; k <= n; k++) { dp[i][j][k] = dp[i - 1][j][k]; if (j - zeroCount >= 0 && k - oneCount >= 0) { // 注意依赖的是 dp[i - 1][j - sm][k - sn] 而不是 dp[i][j - sm][k - sn] dp[i][j][k] = Math.max(dp[i - 1][j - zeroCount][k - oneCount] + 1, dp[i - 1][j][k]); } } } } return dp[strs.length][m][n]; } private int[] getWeight(String str) { int zeroCount = 0; for (int i = 0; i < str.length(); i++) { if (str.charAt(i) == '0') { zeroCount++; } } return new int[]{zeroCount, str.length() - zeroCount}; }} DP123456789101112131415161718192021222324252627282930class Solution { public int findMaxForm(String[] strs, int m, int n) { int[][] dp = new int[m + 1][n + 1]; for (int i = 1; i <= strs.length; i++) { int[] zeroOnes = getZeroOnes(strs[i - 1]); int zeroCount = zeroOnes[0], oneCount = zeroOnes[1]; for (int j = m; j >= 0; j--) { for (int k = n; k >= 0; k--) { if (zeroCount > j || oneCount > k) { dp[j][k] = dp[j][k]; } else { dp[j][k] = Math.max(dp[j][k], dp[j - zeroCount][k - oneCount] + 1); } } } } return dp[m][n]; } private int[] getZeroOnes(String str) { int[] zeroOnes = new int[2]; for (int i = 0; i < str.length(); i++) { char c = str.charAt(i); zeroOnes[c - '0']++; } return zeroOnes; }} Reference474. Ones and Zeroes