1337. 矩阵中战斗力最弱的 K 行 题解 - 力扣(LeetCode) (leetcode-cn.com)
目录
思路
1. 为了便于比较,把每行的士兵个数和行标关联起来形成pair,pair.first表示士兵个数,pair.second表示行标
2. 首先选取前k行做成一个固定大小的最大堆
3. 然后遍历剩余的行,如果战斗力比最大堆堆顶元素弱,那么就替换掉最大堆堆顶元素,然后调整堆,遍历完后最大堆中的k个元素即为最弱的k行
4. 每次从堆顶抽取最大元素,倒序放入最终容器,并调整堆,如此执行k次即可
代码
#define top 1
#define NOP 0
class Solution {
int k;
typedef pair<int, int> cor;
vector<cor> maxHeap;
public:
vector<int> kWeakestRows(vector<vector<int>>& mat, int K) {
k = K;
build_heap(mat);
int size = mat.size();
for (int idx = K; idx != size; ++idx) {
add(maxHeap, num_of_solders(mat[idx]), idx);
}
vector<int> ans(K);
for (int i = K - 1; i != -1; --i) {
ans[i] = maxHeap[top].second;
sink(make_pair(-1, 0), top);
}
return ans;
}
void build_heap(vector<vector<int>>& mat) {
maxHeap.emplace_back(NULL, NULL);
for (int idx = 0; idx != k; ++idx) {
maxHeap.emplace_back(num_of_solders(mat[idx]), idx);
}
for (int pos = k / 2; pos; --pos) {
sink(maxHeap[pos], pos);
}
}
void add(vector<cor>& maxHeap, int num, int idx) {
cor intruder = make_pair(num, idx);
compare(intruder, maxHeap[top]) ? NOP : sink(intruder, top);
}
int sink(cor pebble, int pos) {
int bubble;
while ((bubble = pos * 2) <= k) {
bubble != k && compare(maxHeap[bubble + 1], maxHeap[bubble]) ? ++bubble : 0;
if (compare(pebble, maxHeap[bubble])) break;
maxHeap[pos] = maxHeap[bubble];
pos = bubble;
}
maxHeap[pos] = pebble;
return 0;
}
int compare(cor& intruder, cor& defender) {
return intruder.first > defender.first ||
intruder.first == defender.first && intruder.second > defender.second ?
1 : 0;
}
int num_of_solders(vector<int>& row) {
int start = 0, end = row.size();
int separatrix = end / 2;
while(1) {
if (row[separatrix]) {
if (separatrix + 1 == end || !row[separatrix + 1]) return separatrix + 1;
start = separatrix + 1;
}
else {
if (separatrix == start || row[separatrix - 1]) return separatrix;
end = separatrix;
}
separatrix = start + (end - start) / 2;
}
}
};
运行结果