BM47 寻找第K大
有一个整数数组,请你根据快速排序的思路,找出数组中第 k 大的数。
给定一个整数数组 a ,同时给定它的大小n和要找的 k ,请返回第 k 大的数(包括重复的元素,不用去重),保证答案存在。
要求:时间复杂度 O(nlogn)O(nlogn),空间复杂度 O(1)O(1)
数据范围:0≤n≤10000≤n≤1000, 1≤K≤n1≤K≤n,数组中每个元素满足 0≤val≤100000000≤val≤10000000
思考:
这道题目要求为nlogn,这是我的两种解题思路
- 对数组进行快排,直接输出a[n-1]
- 将数组加入优先队列中,输出至第n个元素
代码:
priority_queue
#include <queue>
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param a int整型vector
* @param n int整型
* @param K int整型
* @return int整型
*/
// bool cmp (int a, int b) {
// return a > b ? true : false ;
// }
struct cmp {
bool operator()(int a, int b) {
return a < b ? true : false ;
}
};
int findKth(vector<int>& a, int n, int K) {
// write code here
std::priority_queue<int, vector<int> , cmp> pq;
for (int i = 0;i < n;i++) pq.push(a[i]);
for (int i = 0;i < K-1;i++) {
std::cout << pq.top() << std::endl;
pq.pop();
}
return pq.top();
}
};
qSort
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param a int整型vector
* @param n int整型
* @param K int整型
* @return int整型
*/
void qSort(vector<int>& num, int begin, int end) {
if (begin > end) return;
int t = num[begin]; // 数轴元素的选择有多种方式,这里默认首元素
int left = begin;
int right = end;
while (left < right)
{
while (left < right && t > num[right]) right--;
if (left < right)
num[left++] = num[right];
while (left < right && t < num[left]) left++;
num[right--] = num[left];
}
num[left] = t;
qSort(num, begin, left-1);
qSort(num, left+1, end);
return;
}
int findKth(vector<int>& a, int n, int K) {
// write code here
qSort(a,0,n-1);
return a[K-1];
}
};
BM46 最小的K个数
给定一个长度为 n 的可能有重复值的数组,找出其中不去重的最小的 k 个数。例如数组元素是4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4(任意顺序皆可)。
数据范围:0≤k,n≤100000≤k,n≤10000,数组中每个数的大小0≤val≤10000≤val≤1000
要求:空间复杂度 O(n)O(n) ,时间复杂度 O(nlogk)O(nlogk)
思考:
先排序,再加入
代码:
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param input int整型vector
* @param k int整型
* @return int整型vector
*/
void qSort(vector<int>& num, int begin, int end) {
if (begin > end) return ;
int t = num[begin];
int l = begin, r = end;
while (l < r)
{
while (l < r && t < num[r]) r--;
if (l < r) num[l++] = num[r];
while (l < r && t > num[l]) l++;
num[r--] = num[l];
}
num[l] = t;
qSort(num, begin, l-1);
qSort(num, l+1, end);
return;
}
vector<int> GetLeastNumbers_Solution(vector<int>& input, int k) {
// write code here
qSort(input,0,input.size()-1);
vector<int> res;
for (int i = 0;i < k;i++) res.push_back(input[i]);
return res;
}
};
BM45 滑动窗口的最大值
给定一个长度为 n 的数组 num 和滑动窗口的大小 size ,找出所有滑动窗口里数值的最大值。
例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。
窗口大于数组长度或窗口长度为0的时候,返回空。
数据范围: 1≤n≤100001≤n≤10000,0≤size≤100000≤siz**e≤10000,数组中每个元素的值满足 ∣val∣≤10000∣val∣≤10000
要求:空间复杂度 O(n)O(n),时间复杂度 O(n)O(n)
思考:
看了一下题目和思路,大概明白是用堆去做,可惜没实现出来,无奈看看题解。
学到的内容,目前对于vector等数据结构的理解,还停留在只存储单一元素。
这道题可以构建一个{元素+下标}的结构体,然后用优先队列(堆)来维护。
代码:
#include <queue>
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param num int整型vector
* @param size int整型
* @return int整型vector
*/
struct d {
int num;
int id;
};
struct cmp {
bool operator()(d a,d b){
return a.num < b.num;
}
};
vector<int> maxInWindows(vector<int>& num, int size) {
// write code here
vector<int> res;
if (size > num.size() || !size) return res;
priority_queue<d, vector<d>, cmp> pq;
int idx = 0;
for (int i = 0;i < num.size();i++)
{
d tmp;
tmp.id = i;
tmp.num = num[i];
pq.push(tmp);
if (i >= size-1) {
while (!pq.empty() && pq.top().id < idx) { // 保证最大值元素在窗口内
pq.pop();
}
res.push_back(pq.top().num);
idx++;
}
}
return res;
}
};