掘金团队号上线,助你 Offer 临门! 点击 查看详情
一、题目描述:
二、思路分析:
这题看起来很明显,是个排序嘛。直接扔优先队列里在pop()一遍就可以了 代码如下
#include<queue>
#include<iostream>
using namespace std;
int main(){
priority_queue<int> q;
int n , m ,k;
cin >> n >> m >> k;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
q.push(i *j);
}
}
while(k > 1){
k--;
q.pop();
}
cout << q.top() << endl;
return 0;
}
直接超时,内存消耗过大 那就是不能都存下来,也就是不能用排序解决这问题
剪枝第一时间就应该想到二分法,二分法的重点在于结果
即:我不考虑要如何排序,而是从结果上思考。
- 题目问的是第k大的值,数的范围为1~m*n 之间.
- 我们假设答案为x,如果有k - 1个值大于x的话
- 那么,如果数据中有x,则答案为x
三、AC 代码:
int left = 1;
int right = m * n;
k = m * n - k + 1;
while (left < right) {
// 注意int类型溢出问题!
int mid = (int)(((long)left + right) / 2);
// 求小于等于 mid 的数量
int row = mid / m;
int count = row * m;
for (int i = row + 1; i <= n; i++) {
count += mid / i;
}
if (count < k) {
left = mid + 1;
} else {
right = mid;
}
}
四、总结:
二分法的思路向来是和其他题干不同的,讲道理这五道题我也没看到哪道题出的中规中矩,看起来拼多多相对于数据结构的掌握,更会考察答题思路多一点。