矩阵中战斗力最弱的 K 行

1、描述

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

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

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

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/the-k-weakest-rows-in-a-matrix
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2、关键字

矩阵,前k个元素,

3、思路

看到前k个元素,就想到优先队列,STL中使用大顶堆实现优先队列,

priority_queue<T> que; // 默认大顶堆,队列从大到小排列。

如果想使用从小到大排列:
priority_queue<T,vector<T>,greater<T> > que;

大顶堆是从大到小,二叉树的结构,但是存储是使用线性结构的队列。

4、notes

直接使用优先队列。
默认大顶堆,从大到小排列。
如果需要自定义排序算法,从小到大,需要写成大于号。
第三个参数:谓词,可以是函数,也可以是lamba表达式的名字
而自己写的使用冒泡排序也是稳定的但是没过。

5、复杂度

时间:O(max(nm,nlgn)),首先遍历了一遍矩阵,复杂度 O(nm),将每行存入优先队列复杂度 O(nlgn)。
空间:O(N)

6、code

优先队列大顶堆

class Solution {
public:
    vector<int> kWeakestRows(vector<vector<int>>& mat, int k) {
        priority_queue<pair<int,int> >que;  // 构造优先队列的基本元素pair
        vector<int>res;
        int n = mat.size();
        for(int i = 0; i < n; i++){  // 遍历mat 组装 优先队列的基本元素
            int cnt = 0;
            for(auto elem : mat[i]){
                cnt += elem;
            }
            que.push({cnt,i});  // 使用的是push方法
        }
        while(que.size() > k) que.pop();  // STL默认大顶堆,如此把强队删除,
        while(!que.empty()){
            res.push_back(que.top().second);
            que.pop();
        }
        reverse(res.begin(),res.end());
        return res;

    }
};

改写成为小顶堆 的优先队列:
1、自定义比较函数:使用一个auto关键字 + lamba表达式
2、使用自定义排序的优先队列时候的3个参数,

class Solution {
public:
    vector<int> kWeakestRows(vector<vector<int>>& mat, int k) {
        auto cmp = [](pair<int,int> & a,pair<int,int>& b){
            if(a.first == b.first){
                return a.second > b.second;  // 这里一个奇怪的现象,明明说的是变成从小到大排序,却要写成 大于号!
            }
            else{
                return a.first > b.first;
            }
        };  // 这里有一个分号


        priority_queue < pair<int,int>, vector<pair<int,int> >,decltype(cmp) > que(cmp);  // 构造优先队列的基本元素pair
        //priority_queue<pair<int,int> vector<pair<int,int>,greator<pair<int,int>> >que;// 构造优先队列的基本元素pair
        vector<int>res;
        int n = mat.size();
        for(int i = 0; i < n; i++){  // 遍历mat 组装 优先队列的基本元素
            int cnt = 0;
            for(auto elem : mat[i]){
                cnt += elem;
            }
            que.push({cnt,i});  // 使用的是push方法
        }
        for(int i = 0; i< k; i++){
            res.push_back(que.top().second);
            que.pop();
        }

        return res;

    }
};
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值