《LeetCode之每日一题》:112.矩阵中战斗力最弱的 K 行
Posted 是七喜呀!
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《LeetCode之每日一题》:112.矩阵中战斗力最弱的 K 行相关的知识,希望对你有一定的参考价值。
题目链接: 矩阵中战斗力最弱的 K 行
有关题目
给你一个大小为 m * n 的矩阵 mat,矩阵由若干军人和平民组成,分别用 1 和 0 表示。
请你返回矩阵中战斗力最弱的 k 行的索引,按从最弱到最强排序。
如果第 i 行的军人数量少于第 j 行,或者两行军人数量相同但 i 小于 j,那么我们认为第 i 行的战斗力比第 j 行弱。
军人 总是 排在一行中的靠前位置,也就是说 1 总是出现在 0 之前。
示例 1:
输入: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
输出:[2,0,3]
解释:
每行中的军人数目:
行 0 -> 2
行 1 -> 4
行 2 -> 1
行 3 -> 2
行 4 -> 5
从最弱到最强对这些行排序后得到 [2,0,3,1,4]
示例 2:
输入:mat =
[[1,0,0,0],
[1,1,1,1],
[1,0,0,0],
[1,0,0,0]],
k = 2
输出:[0,2]
解释:
每行中的军人数目:
行 0 -> 1
行 1 -> 4
行 2 -> 1
行 3 -> 1
从最弱到最强对这些行排序后得到 [0,2,3,1]
提示:
m == mat.length
n == mat[i].length
2 <= n, m <= 100
1 <= k <= m
matrix[i][j] 不是 0 就是 1
题解
方法一:硬编码数字
将每一行的士兵数量x100+索引存到一个新的列表里,然后对这个列表进行排序,取前面的k位对100取余即是需要的索引值。
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int sum(int mat[], int col){
int sum = 0;
for (int i = 0; i < col ; i++){
if (mat[i] == 0) break;
sum += mat[i];
}
return sum;
}
int cmp(int* a, int* b){
return *a - *b;
}
int* kWeakestRows(int** mat, int matSize, int* matColSize, int k, int* returnSize){
int* list = (int*)malloc(matSize * sizeof(int));
int* ans = (int*)malloc(k * sizeof(int));
for (int i = 0; i < matSize; i++){
list[i] = sum(mat[i], *matColSize) * 100 + i;
}
//排序
qsort(list, matSize, sizeof(int), cmp);
*returnSize = k;
for (int i = 0; i < k; i++){
ans[i] = list[i] % 100;
}
return ans;
}
时间复杂度:O(M * N)
空间复杂度:O(M)
方法二:二分查找 + 堆
思路:
题目中保证:军人总是排在一行中的靠前位置,也就是说 1 总是出现在 0 之前。
所以我们使用二分查找,找到最后一个1的位置pos,那么该行军人总数为pos + 1
当我们得到每行的战斗力之后,我们使用一个小根堆来找到最弱的k行的索引
class Solution {
public:
vector<int> kWeakestRows(vector<vector<int>>& mat, int k) {
int m = mat.size(), n = mat[0].size();
vector<pair<int, int>> power;//pair类
for (int i = 0; i < m; ++i) {
int l = 0, r = n - 1, pos = -1;//二分查找,初始化pos为-1
while (l <= r) {
int mid = (l + r) / 2;
if (mat[i][mid] == 0) {
r = mid - 1;
}
else {
pos = mid;
l = mid + 1;
}
}
power.emplace_back(pos + 1, i);
}
priority_queue q(greater<pair<int, int>>(), move(power));//小根堆
vector<int> ans;
for (int i = 0; i < k; ++i) {//拿出前k个索引
ans.push_back(q.top().second);
q.pop();
}
return ans;
}
};
以上是关于《LeetCode之每日一题》:112.矩阵中战斗力最弱的 K 行的主要内容,如果未能解决你的问题,请参考以下文章