力扣练题之1337.矩阵中战斗力最弱的第K行

题目描述

给你一个大小为 m * n 的矩阵 mat,矩阵由若干军人和平民组成,分别用 1 和 0 表示。

请你返回矩阵中战斗力最弱的 k 行的索引,按从最弱到最强排序。

如果第 i 行的军人数量少于第 j 行,或者两行军人数量相同但 i 小于 j,那么我们认为第 i 行的战斗力比第 j 行弱。

军人 总是 排在一行中的靠前位置,也就是说 1 总是出现在 0 之前。

我自己的暴力解法:

class Solution:
    def kWeakestRows(self, mat, k: int):
        hashmap = {}
        a_list = []
        for i in range(len(mat)):
            sum_ = sum(mat[i])
            hashmap[i] = sum_ # {0:10,1:12,2:13}
        d_order = sorted(hashmap.items(),key=lambda x:x[1],reverse=False)
        print(d_order)
        for i in range(k):
            a_list.append(d_order[i][0])
        return a_list

我先对每行士兵的战力进行计算,计算后将每行士兵的行号和战力值保存在字典中,然后对字典根据战力由弱到强的顺序排序,然后遍历列表把士兵行号取出来,存到列表中,截取前面k个就是最弱的第K行。

class Solution:
    def kWeakestRows(self, mat, k: int):
        a = [sum(row) for row in mat] #[2, 4, 1, 2, 5]计算出了每行的战力
        print(a)
        ma = max(a)
        mi = min(a)
        ans = []
        while True:
            for index, val in enumerate(a):
                if val == mi:
                    ans.append(index)
                    a[index] = ma + 1
                    if len(ans)==k:
                        return ans
            mi = min(a)

这个方法是先把每行的战力计算出来保存在一个列表里面,这个列表的顺序就是之前的行号。然后枚举列表,找到最小值,更新最小值。
依次按照战力由弱到强将行号保存到列表中。这个方法还有我自己理解还有优化空间。

class Solution:
    def kWeakestRows(self, mat: List[List[int]], k: int) -> List[int]:
        a = [sum(row) for row in mat]
        mi = min(a)
        ma = max(a)
        ans = []
        while True:
            ans.append(a.index(mi))
            a[a.index(mi)] = ma + 1
            if len(ans) == k:
                break
            mi = min(a)
        return ans

这样优化后减少了每找到一个值就需要枚举一次列表。

方法2:
每一行都按顺序报数,谁先出现0谁最弱
因为题目告诉“1 总是出现在 0 之前”

  1. 遍历每一行的第一列是否是0,谁是0谁最弱,记录行号,为了简化处理整行都是1的情况,我们可以在每一行末尾都添加一个0
  2. 检查每一行的第二列……以此循环
  3. 在这个过程中如过记录的数量打到k,直接return跳出即可

因为题意是说军人必定在前面,所以就有了哪一行先出现0,哪一行的战斗力就最弱。

class Solution:
    def kWeakestRows(self, mat, k: int):
        ans = []
        column = 0
        while True:
            for index,row in enumerate(mat):
                row.append(0)
                if row[column] == 0 and index not in ans:
                    ans.append(index)
                    if len(ans) == k:
                        return ans
            column += 1

我们首先定义一个column代表列数。然后我们看是枚举每行,检查每行的第一列是不是为0,如果是0并且这一行的行号没有在目标列表中,那么就添加该行号,然后检查目标列表长度是不是等于K,满足条件了之后就返回列表。
依次检查,检查完了第一列再检查第二列。

本题官方解答链接
官方解答中的二分查找+堆以及二分查找+快速选择有待学习。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老师好,我是刘同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值