如何在頁面上實現一個圓形的可點選區域
阿新 • • 發佈:2020-08-29
問題:
給定一組只包含'0' '1' 的字串,給定兩個正整數m和n,問,要使用m個'0' n個'1',能最多構成多少個給出字串組中的字串。
Example 1: Input: strs = ["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: strs = ["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". Constraints: 1 <= strs.length <= 600 1 <= strs[i].length <= 100 strs[i] consists only of digits '0' and '1'. 1 <= m, n <= 100
解法:DP(動態規劃)0-1 knapsack problem(0-1揹包問題)
1.確定【狀態】:
- 可選擇的元素:前 i 個字串
- 和:
- m:m個 ' 0 '
- n:n個 ' 1 '
2.確定【選擇】:
- 選擇當前的字串strs[i]
- 不選擇當前的字串strs[i]
3. dp[i][m][n]的含義:
前 i 個字串中,用m個'0' n個'1' 最多能組成的字串個數。
4. 狀態轉移:
dp[i][m][n]= OR {
- 選擇 strs[i]:dp[i-1][m-strs[i].count('0')][n-strs[i].count('1')] + 1:=前 i-1 個元素中,用M個'0'N個'1'最多可組成的字串個數 + strs[i]自己一個
- 不選擇 strs[i]:dp[i-1][m][n]:=前 i-1 個元素中,用m個'0'n個'1'最多可組成的字串個數。
}
5. base case:
- dp[0][m][n]=0
- dp[i][0][0]=0
程式碼參考:
1 class Solution { 2 public: 3 //dp[i][m][n]:in first i strs, the max number of strs can be formed by m 0s and n 1s. 4 //case_1.select strs[i] : = dp[i-1][m-strs[i].count('0')][n-strs[i].count('1')]+15 //case_2.not select strs[i]: = dp[i-1][m][n] 6 //dp[i][m][n] = max(case_1, case_2) 7 //base: dp[0][m][n]=0 8 //dp[i][0][0]=0 9 int findMaxForm(vector<string>& strs, int m, int n) { 10 vector<vector<vector<int>>> dp(strs.size()+1, vector<vector<int>>(m+1, vector<int>(n+1, 0))); 11 for(int i=1; i<=strs.size(); i++) { 12 int cout_1 = count(strs[i-1].begin(), strs[i-1].end(), '1'); 13 int cout_0 = count(strs[i-1].begin(), strs[i-1].end(), '0'); 14 for(int M=0; M<=m; M++) { 15 for(int N=0; N<=n; N++) { 16 if(M-cout_0>=0 && N-cout_1>=0) { 17 dp[i][M][N] = max(dp[i-1][M-cout_0][N-cout_1]+1, dp[i-1][M][N]); 18 } else { 19 dp[i][M][N] = dp[i-1][M][N]; 20 } 21 } 22 } 23 } 24 return dp[strs.size()][m][n]; 25 } 26 };
♻️ 優化:空間複雜度:3維->2維
去掉 i
將 m和n 倒序遍歷。
理由參考:https://www.cnblogs.com/habibah-chang/p/13581649.html
程式碼參考:
1 class Solution { 2 public: 3 //dp[i][m][n]:in first i strs, the max number of strs can be formed by m 0s and n 1s. 4 //case_1.select strs[i] : = dp[i-1][m-strs[i].count('0')][n-strs[i].count('1')]+1 5 //case_2.not select strs[i]: = dp[i-1][m][n] 6 //dp[i][m][n] = max(case_1, case_2) 7 //base: dp[0][m][n]=0 8 //dp[i][0][0]=0 9 int findMaxForm(vector<string>& strs, int m, int n) { 10 vector<vector<int>> dp(m+1, vector<int>(n+1, 0)); 11 for(int i=1; i<=strs.size(); i++) { 12 int cout_1 = count(strs[i-1].begin(), strs[i-1].end(), '1'); 13 int cout_0 = count(strs[i-1].begin(), strs[i-1].end(), '0'); 14 for(int M=m; M>=0; M--) { 15 for(int N=n; N>=0; N--) { 16 if(M-cout_0>=0 && N-cout_1>=0) { 17 dp[M][N] = max(dp[M-cout_0][N-cout_1]+1, dp[M][N]); 18 } 19 } 20 } 21 } 22 return dp[m][n]; 23 } 24 };