多執行緒之interrupt與優雅停止一個執行緒
阿新 • • 發佈:2022-01-29
題目連結:
給你一個二進位制字串陣列 strs
和兩個整數 m
和 n
。
請你找出並返回 strs
的最大子集的長度,該子集中 最多 有 m
個 0
和 n
個 1
。
如果 x
的所有元素也是 y
的元素,集合 x
是集合 y
的 子集 。
輸入: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
解題思路
該題可以轉為01揹包問題。將揹包看成有兩個口袋,一個口袋裝0
,一個口袋裝1
,而strs
中每個物品的重量有兩個維度,一個重量維度是0
的個數,另一個重量維度是1
的個數。
-
確定dp陣列以及其下標的含義
該題的dp陣列是一個二維陣列(是因為物品的重量有兩個維度,本質還是
dp[i][j]
表示最多有i
個0
和j
個1
的strs
的最大子集的長度。 -
確定遞推公式
-
當物品
[i][j]
裝不進揹包時,當前的dp[i][j]
= 之前的dp[i][j]
-
當物品
[i][j]
裝不進揹包時,可以選擇裝或不裝-
選擇不裝,當前的
dp[i][j]
= 之前的dp[i][j]
-
選擇裝,當前的
dp[i][j]
= 之前的dp[i - 當前物品中0的個數][j - 當前物品中1的個數] + 1
-
所以可以得到遞推公式:
dp[i][j] = max (dp[i][j], dp[i - 當前物品中0的個數][j - 當前物品中1的個數] + 1)
-
-
dp陣列的初始化
與
-
確定遍歷順序
先遍歷物品,後遍歷揹包容量並且是從後向前遍歷。
C++
class Solution { public: int findMaxForm(vector<string>& strs, int m, int n) { // 1.dp[i][j]表示最多有i個0和j個1的strs的最大子集的大小 // 3.dp初始化:因為物品價值不會是負數,dp初始為0,保證遞推的時候dp[i][j]不會被初始值覆蓋。 vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0)); // m是0的個數,n是1的個數 // 首先遍歷物品,計算每個物品中0的個數和1的個數 for(int k = 0; k < strs.size(); k++) { int zeroNum = 0, oneNum = 0; for (char c : strs[k]) { if (c == '0') { zeroNum++; } else { oneNum++; } } // 遍歷揹包容量(類似於一個揹包有兩個小包,第一個小包裝0,第二個小包裝1) for (int i = m; i >= zeroNum; i--) { for (int j = n; j >= oneNum; j--) { // 2.遞推公式 dp[i][j] = max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1); } } } return dp[m][n]; } };
JavaScript
/** * @param {string[]} strs * @param {number} m * @param {number} n * @return {number} */ var findMaxForm = function(strs, m, n) { const dp = Array(m + 1); for (let i = 0; i < m + 1; i++) { dp[i] = Array(n + 1).fill(0); } // 遍歷物品 for (const s of strs) { let zeroNum = 0, oneNum = 0; for (const c of s) { if (c === '0') { zeroNum++; } else { oneNum++; } } //遍歷揹包 for (let i = m; i >= zeroNum; i--) { for (let j = n; j >= oneNum; j--) { dp[i][j] = Math.max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1); } } } return dp[m][n]; };
-
時間複雜度:O(k*m*n),k是strs的大小,m是題目中要求的0的個數,n是題目要求的1的個數
-