Given a m * n
matrix mat
of ones (representing soldiers) and zeros (representing civilians), return the indexes of the k
weakest rows in the matrix ordered from the weakest to the strongest.
A row i is weaker than row j, if the number of soldiers in row i is less than the number of soldiers in row j, or they have the same number of soldiers but i is less than j. Soldiers are always stand in the frontier of a row, that is, always ones may appear first and then zeros.
Example 1:
Input: mat = [[1,1,0,0,0], [1,1,1,1,0], [1,0,0,0,0], [1,1,0,0,0], [1,1,1,1,1]], k = 3 Output: [2,0,3] Explanation: The number of soldiers for each row is: row 0 -> 2 row 1 -> 4 row 2 -> 1 row 3 -> 2 row 4 -> 5 Rows ordered from the weakest to the strongest are [2,0,3,1,4]
Example 2:
Input: mat = [[1,0,0,0], [1,1,1,1], [1,0,0,0], [1,0,0,0]], k = 2 Output: [0,2] Explanation: The number of soldiers for each row is: row 0 -> 1 row 1 -> 4 row 2 -> 1 row 3 -> 1 Rows ordered from the weakest to the strongest are [0,2,3,1]
Constraints:
m == mat.length
n == mat[i].length
2 <= n, m <= 100
1 <= k <= m
matrix[i][j]
is either 0 or 1.
題目大意:
給你一個大小為 m * n 的方陣 mat,方陣由若干軍人和平民組成,分別用 0 和 1 表示。
請你返回方陣中戰斗力最弱的 k 行的索引,按從最弱到最強排序。
如果第 i 行的軍人數量少於第 j 行,或者兩行軍人數量相同但 i 小於 j,那么我們認為第 i 行的戰斗力比第 j 行弱。
軍人 總是 排在一行中的靠前位置,也就是說 1 總是出現在 0 之前。
題目解析:
每一行的戰斗力很容易求出來,但是要返回的是戰斗力對應的行號,所以我們需要將每行的編號和行戰斗力綁定起來,以便根據戰斗力排序后很容易取出對應的行號。
綁定方式多種多樣,二維數組、結構體或者pair都是可以的。
C++代碼一:
1 vector<int> kWeakestRows(vector<vector<int>>& mat, int k) { 2 vector<int> ans(k); 3 int m = mat.size(); 4 vector<array<int, 2>> v(m); 5 for (int i = 0; i < m; ++i) { 6 int c = 0; 7 for (int j = 0; j < mat[i].size(); ++j) { 8 c += mat[i][j]; 9 } 10 v[i] = {c, i}; 11 } 12 sort(v.begin(), v.end()); 13 for (int i = 0; i < k; ++i) { 14 ans[i] = v[i][1]; 15 } 16 return ans; 17 }
C++代碼二:
1 vector<int> kWeakestRows(vector<vector<int>>& mat, int k) { 2 vector<int> ans(k); 3 int r = mat.size(), c = (mat.size() == 0 ? 0 : mat[0].size()), index = 0; 4 vector<bool> visited(r, false); //判斷某一行號是否被選擇 5 for (int j = 0; j < c; ++j) { 6 for (int i = 0; i < r; ++i) { 7 if (visited[i]) //如果第i行已經被選擇,則不需要考慮這一行的軍人數 8 continue; 9 if (index >= k) //提前找到了k行,則跳出兩層循環 10 goto a; 11 if (index < k && mat[i][j] == 0) { 12 ans[index++] = i; 13 visited[i] = true; 14 } 15 } 16 } 17 //可能有些行不存在平民,那么最終村在index + 1 < k的情況,需要按照行號從小到大存入返回vector 18 for (int i = 0; i < r; ++i) { 19 if (index < k && !visited[i]) { 20 visited[i] = true; 21 ans[index++] = i; 22 } 23 } 24 a:; 25 return ans; 26 }
python3代碼:
1 class Solution: 2 def kWeakestRows(self, mat: List[List[int]], k: int) -> List[int]: 3 s = [(sum(m), i) for i, m in enumerate(mat)] 4 r = sorted(s) 5 return [r[1] for r in r[:k]]