• leetcode 1337. The K Weakest Rows in a Matrix


    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]]
  • 相关阅读:
    android:background背景图片被拉伸问题
    面试积累(String和StringBuffer, StringBuilder的理解)
    面试积累(冒泡排序和选择排序)
    面试积累(java的内存分析)
    面试积累(java配置环境变量)
    异常积累(SQLException)
    【linux】fdisk磁盘分区
    【走马观花】十一月十八日通州雨
    【linux】CentOS查看硬件信息
    【linux】go安装及配置
  • 原文地址:https://www.cnblogs.com/qinduanyinghua/p/12272370.html
Copyright © 2020-2023  润新知