剑指offer 最小的k个数 、 leetcode 215. Kth Largest Element in an Array 、295. Find Median from Data Stream(剑指 数据流中位数)
注意multiset的一个bug:
multiset带一个参数的erase函数原型有两种。一是传递一个元素值,如上面例子代码中,这时候删除的是集合中所有值等于输入值的元素,并且返回删除的元素个数;另外一种是传递一个指向某个元素的iterator,这时候删除的就是这个对应的元素,无返回值。
https://www.cnblogs.com/lakeone/p/5600494.html
删除的时候一定不能删除指针,只能删除迭代器
leetcode那个题就是在这个地方出错的:
Expected: 2
如果container.erase(*con),最后小根堆的大小就只有19个
container.erase(con)才是正确的
剑指offer 最小的k个数:
这是partition版本的
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
vector<int> result;
int length = input.size();
if(input.empty() || length <= || k <= || length < k)
return result;
int start = ;
int end = length - ;
int index = partition(input,start,end);
while(index != k-){
if(index > k-){
end = index - ;
index = partition(input,start,end);
}
else{
start = index + ;
index = partition(input,start,end);
}
}
for(int i = ;i < k;i++)
result.push_back(input[i]);
return result;
}
int partition(vector<int> &input,int start,int end){
int small = start - ;
for(int i = start;i < end;i++){
if(input[i] < input[end]){
small++;
if(small != i)
swap(input,small,i);
}
}
small++;
swap(input,small,end);
return small;
}
void swap(vector<int>& input,int a,int b){
int tmp = input[a];
input[a] = input[b];
input[b] = tmp;
}
};
这是基于大根堆的:
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
vector<int> output;
int length = input.size();
if(input.empty() || k <= || length < k)
return output;
multiset<int,greater<int>> numbers;
multiset<int,greater<int>>::iterator greaternumber; vector<int>::iterator iter = input.begin();
for(;iter != input.end();iter++){
if(numbers.size() < k)
numbers.insert(*iter);
else{
greaternumber = numbers.begin();
if(*greaternumber > *iter){
numbers.erase(*greaternumber);
numbers.insert(*iter);
}
}
}
for(greaternumber = numbers.begin();greaternumber != numbers.end();greaternumber++){
output.push_back(*greaternumber);
}
return output;
}
};
leetcode 215. Kth Largest Element in an Array
使用小根堆
错误写法:
在这个情况:{3,2,3,1,2,4,5,5,6,7,7,8,2,3,1,1,1,10,11,5,6,2,4,7,8,5,6},会报错
错误在container.erase(*con),正确应该是container.erase(con)。erase(*con)删除的是数值,比如top是3,会把container里面所有的3都删除掉 ,erase(con)删除的是指针,只删除top的这个值
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
multiset<int,less<int>> container;
multiset<int,less<int>>::iterator con; for(int i = ;i < nums.size();i++){
if(container.size() < k)
container.insert(nums[i]);
else{
con = container.begin();
if(*con < nums[i]){
container.erase(*con);
container.insert(nums[i]);
}
}
}
con = container.begin();
return *con;
}
};
正确写法:
可以写
if(length <= 0 || k <= 0 || length < k)
return -1;
针对这个判断条件,有可能输入的不全是正数,返回-1就有问题,原题目中其实是排除了这些边界条件的
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
multiset<int,less<int>> container;
multiset<int,less<int>>::iterator con;
//if(length <= 0 || k <= 0 || length < k)
//return -1;
for(int i = ;i < nums.size();i++){
if(container.size() < k)
container.insert(nums[i]);
else{
con = container.begin();
if(*con < nums[i]){
container.erase(con);
container.insert(nums[i]);
}
}
}
con = container.begin();
return *con;
}
};
使用partition的方式:
注意这里要增加end = index - 1和start = index + 1,因为这里不是递归,是使用的循环。如果你直接把end换成index - 1带入patition函数,对于之后的partition函数,这个end实际上还是没变的。
没有真正达到所以1/2的目的。
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
int n = nums.size();
k = n - k;
int start = ,end = nums.size() - ;
int index = partition(nums,start,end);
int freq = ;
while(index != k){
if(index > k){
end = index - ;
index = partition(nums,start,end);
}
else{
start = index + ;
index = partition(nums,start,end);
}
}
return nums[index];
}
int partition(vector<int>& nums,int start,int end){
int index = start - ;
for(int i = start;i < end;i++){
if(nums[i] < nums[end]){
index++;
if(index != i)
swap(nums[index],nums[i]);
}
}
index++;
swap(nums[index],nums[end]);
return index;
}
};
80. Median
这个题是在无序数组中找经过排序后的中间位置的值。实际上这个题和Kth Largest Element in an Array差不多,Kth Largest Element in an Array是求第k大,这个题是限定了k是中间位置,并且要求时间复杂度是O(n),所以使用partition的方式就可以。
时间复杂度分析:
https://rcoh.me/posts/linear-time-median-finding/
这是平局时间复杂度
实际上就是O(N) + O(N/2) + O(N/4) + O(N/8)....,使用等比数列求和公式:
就可以得到是一个O(2N)的复杂度,即O(N)
class Solution {
public:
/**
* @param nums: A list of integers
* @return: An integer denotes the middle number of the array
*/
int median(vector<int> &nums) {
// write your code here
int start = ,end = nums.size() - ;
int index = partition(nums,start,end);
int k = (nums.size() - )/;
while(k != index){
if(index < k){
start = index + ;
index = partition(nums,start,end);
}
else{
end = index - ;
index = partition(nums,start,end);
}
}
return nums[index];
}
int partition(vector<int>& nums,int start,int end){
int index = start - ;
for(int i = start;i < end;i++){
if(nums[i] < nums[end]){
index++;
if(i != index)
swap(nums[i],nums[index]);
}
}
index++;
swap(nums[end],nums[index]);
return index;
}
};
295. Find Median from Data Stream
使用两个堆进行存储,一个是大根堆,即存储所有较小的数;一个是小根堆,即存储所有较大的数。使用priority_queue来代表大小根堆。
class MedianFinder {
public:
/** initialize your data structure here. */
MedianFinder() { } void addNum(int num) {
if(p.size() == || p.top() > num)
p.push(num);
else
q.push(num);
if(p.size() > q.size() + ){
int tmp = p.top();
p.pop();
q.push(tmp);
}
if(q.size() > p.size()){
int tmp = q.top();
q.pop();
p.push(tmp);
}
} double findMedian() {
return p.size() > q.size() ? p.top() * 1.0 : (p.top() + q.top())/2.0;
}
priority_queue<int,vector<int>,less<int>> p;
priority_queue<int,vector<int>,greater<int>> q;
};
剑指offer 最小的k个数 、 leetcode 215. Kth Largest Element in an Array 、295. Find Median from Data Stream(剑指 数据流中位数)的更多相关文章
- 网易2016 实习研发工程师 [编程题]寻找第K大 and leetcode 215. Kth Largest Element in an Array
传送门 有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数. 给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在. 测试样例: [1,3,5, ...
- LN : leetcode 215 Kth Largest Element in an Array
lc 215 Kth Largest Element in an Array 215 Kth Largest Element in an Array Find the kth largest elem ...
- [LeetCode] 215. Kth Largest Element in an Array 数组中第k大的数字
Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...
- [leetcode]215. Kth Largest Element in an Array 数组中第k大的元素
Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...
- leetcode 215. Kth Largest Element in an Array
Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...
- Java for LeetCode 215 Kth Largest Element in an Array
Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...
- C#版 - Leetcode 215. Kth Largest Element in an Array-题解
版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. C#版 - L ...
- LeetCode OJ 215. Kth Largest Element in an Array 堆排序求解
题目链接:https://leetcode.com/problems/kth-largest-element-in-an-array/ 215. Kth Largest Element in an A ...
- Leetcode 之 Kth Largest Element in an Array
636.Kth Largest Element in an Array 1.Problem Find the kth largest element in an unsorted array. Not ...
随机推荐
- [javaSE] 多线程(售票例子)
需求:简单的买票程序,多个窗口卖票,多线程 定义一个类Ticket实现Runnable接口, 定义成员属性int类型的票数nums 实现run()方法,run方法中 while(true)的死循环,打 ...
- [JAVA IDEA]在使用maven项目中,无法读取resources文件夹中的配置文件的一种解决方案
1.在通过配置文件来连接数据库时,在resouces文件中放入了db.properties配置文件,但无法正常读取到 读取配置文件信息的代码: InputStream input=JdbcUtil.c ...
- java EE 新手入门了解
郑重申明:本文转载至https://blog.csdn.net/Neuf_Soleil/article/details/80962686,在此深表感谢! 为什么选择java? 想必有很多初学者会像我一 ...
- [Telegram X]旧版分享 突破被锁群组
Telegram X的锁群是由于 App Store 审核时发现Telegram官方并不限制18+.社会舆论等的讨论:在 版本 5.0.2 (版本号825487096)时就已经封禁该类群组 注:可能由 ...
- 解决:启动项目报错 java.lang.NoClassDefFoundError: org/apache/commons/fileupload/FileItemFactory
前言:项目在 spring-mvc.xml 文件中配置了上传文件拦截,结果启动报错 java.lang.NoClassDefFoundError: org/apache/commons/fileupl ...
- Web Service与Apache CXF 框架
一.WebService简介 为了支持跨网络的机器间相互操作交互而设计,用于开发分布式的互操作的应用程序组件. Web Service服务通常被定义为一组模块化的API,它们可以通过网络进行调用,来执 ...
- 浅谈 Linux 下的 SSH1, SSH2
SSH:Secure Shell .是一种安全协议. 常见的应用场景是远程控制台登陆. SSH1免费,SSH2收费. 其实 SSH 并不只是在 Linux 和 Unix 下使用,他们同样在 Win ...
- QT5.9 新特性与版本回顾
原文链接: http://blog.qt.io/blog/2017/05/31/qt-5-9-released 翻译内容如下,采用的是第三方某在线翻译软件,所以有些地方不是太精确,纵然大吉做了一定的调 ...
- JAVA - JDK 1.8 API 帮助文档-中文版
JAVA - JDK 1.8 API 帮助文档-中文版 百度云链接: https://pan.baidu.com/s/1_7FFadw1a6J0qTfx2FzqPQ 密码: 41n4
- Python进阶内容(一)--- 高阶函数 High order function
0. 问题 # 本文将围绕这段代码进行Python中高阶函数相关内容的讲解 # 文中所有代码的兼容性要求为:Python 3.6,IPython 6.1.0 def addspam(fn): def ...