【hihoCoder】#1133 : 二分·二分查找之k小数
题目描述
在上一回里我们知道Nettle在玩《艦これ》,Nettle的镇守府有很多船位,但船位再多也是有限的。Nettle通过捞船又出了一艘稀有的船,但是已有的N(1≤N≤1,000,000)个船位都已经有船了。所以Nettle不得不把其中一艘船拆掉来让位给新的船。Nettle思考了很久,决定随机选择一个k,然后拆掉稀有度第k小的船。 已知每一艘船都有自己的稀有度,Nettle现在把所有船的稀有度值告诉你,希望你能帮他找出目标船。
输入
第1行:2个整数N,k。N表示数组长度,
第2行:N个整数,表示a[1..N],保证不会出现重复的数,1≤a[i]≤2,000,000,000。
输出
第1行:一个整数t,表示t在数组中是第k小的数,若K不在数组中,输出-1。
样例输入
10 4
1732 4176 2602 6176 1303 6207 3125 1 1011 6600
样例输出
1732
算法
无意间刷到这题,并且原题已经给出算法的提示。趁着这题让我回顾了下快速排序,并且在这边先记录这题算法的核心思想。
快速排序每次都能确定一个元素的位置,也就是说,能知道这个元素是数组中第几小的数。那么将k与该元素所在的位置进行比较:
如果正好就是第k小的数,直接打印退出即可;
如果该位置比k大,说明第k小的数在该元素左边的那堆数中,往左边走,重复之前的步骤;
如果该位置比k小,说明第k小的数在该元素右边的那堆数中,往右边走,重复之前的步骤。
由于不是进行全局的交换位置,每次都交换需要寻找的区域,所以时间复杂度为O(logn);但是当遇见一开始就完全有序的情况,或者是从大到小排序的情况就比较蛋疼,所以最后能放置一个标志位,如果一轮下来不曾交换可以直接通过数学的方法计算出第k小的位置。当然,这是在本题中这么说,如果真实的快排中,选择主元是一门比较大的学问。
当然这题也可以用堆排序实现,维护一个N-k这么大的最小堆,最后的堆顶就是需要找的元素,说实话借助优先队列的话,还是十分简单的。
代码
#include <iostream>
using namespace std;
void Swap(int &a, int &b)
{
int tmp = a;
a = b;
b = tmp;
}
int main()
{
// freopen("stdin.txt", "r", stdin);
int N, k;
scanf("%d %d", &N, &k);
int Arr[N];
for (int i = 0; i < N; i++)
{
scanf("%d", &Arr[i]);
}
if (k < 1 || k > N)
printf("-1\n");
// 算法主体
int left = 0, right = N-1;
while(left <= right)
{
int pivot = Arr[left];
int p = left, q = right;
while (1)
{
while (Arr[q] >= pivot && q > p)
q--;
while (Arr[p] <= pivot && p < q)
p++;
if (p < q)
swap(Arr[p], Arr[q]);
else
break;
}
Swap(Arr[left], Arr[p]);
// for (int f = 0; f < N; f++)
// cout << Arr[f] << ' ';
// cout << endl;
if(p == k-1)
{
printf("%d\n", Arr[p]);
break;
}
else if (p > k-1)
right = p - 1;
else
left = p + 1;
}
return 0;
}
【hihoCoder】#1133 : 二分·二分查找之k小数的更多相关文章
- hihoCoder 1133 二分·二分查找之k小数(TOP K算法)
#1133 : 二分·二分查找之k小数 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在上一回里我们知道Nettle在玩<艦これ>,Nettle的镇守府有很 ...
- hiho week 37 P1 : 二分·二分查找之k小数
P1 : 二分·二分查找之k小数 Time Limit:10000ms Case Time Limit:1000ms Memory Limit:256MB 描述 在上一回里我们知道Nettle在玩&l ...
- 查找第K小数
题目描述 查找一个数组的第K小的数,注意同样大小算一样大. 如 2 1 3 4 5 2 第三小数为3. 输入描述: 输入有多组数据.每组输入n,然后输入n个整数(1<=n<=1000), ...
- 【九度OJ】题目1174:查找第K小数 解题报告
[九度OJ]题目1174:查找第K小数 解题报告 标签(空格分隔): 九度OJ 原题地址:http://ac.jobdu.com/problem.php?pid=1174 题目描述: 查找一个数组的第 ...
- 【HIHOCODER 1133】 二分·二分查找之k小数
描述 在上一回里我们知道Nettle在玩<艦これ>,Nettle的镇守府有很多船位,但船位再多也是有限的.Nettle通过捞船又出了一艘稀有的船,但是已有的N(1≤N≤1,000,000) ...
- hiho一下 第三十七周 二分查找之k小数
题目链接:http://hihocoder.com/contest/hiho37/problem/1 , 简单二分. 算法: 题目即为求一个无序数组数组中第k小的数,由于数据量太大,排序是会超时的. ...
- hihoCoder#1133 二分·二分查找之k小数
原题地址 经典问题了,O(n)时间内找第k大的数 代码: #include <iostream> using namespace std; int N, K; int *a; int se ...
- Hiho : 二分·二分查找之k小数
时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在上一回里我们知道Nettle在玩<艦これ>,Nettle的镇守府有很多船位,但船位再多也是有限的.Nettl ...
- hihocoder1133 二分·二分查找之k小数
思路: 类似于快排的分治算法. 实现: #include <iostream> #include <cstdio> #include <algorithm> #in ...
随机推荐
- 利用python同步windows和linux文件
写python脚本的初衷,每次在windows编辑完文件后,想同步到linux上去,只能够登录服务器,然后再利用网络copy,重复性很大,就想着能不能写一个小脚本帮我同步 逻辑:比对本地和服务器文件的 ...
- Apache Thrift的C++多线程编程定式
Facebook贡献给Apache的开源RPC组件Thrift有着广泛的应用,C++中使用Thrift也十分普遍,但由于Thrift的Handler会被多个线程调用,因而多线程中应用并不直接的友好,利 ...
- EF6 学习笔记(二):操练 CRUD 增删改查
EF6学习笔记总目录 ASP.NET MVC5 及 EF6 学习笔记 - (目录整理) 接上篇: EF6 学习笔记(一):Code First 方式生成数据库及初始化数据库实际操作 本篇原文链接: I ...
- WPF中TreeView的+-号和连线style的一种实现
最近又开始跟WPF打交道,项目里面用到了TreeView这个控件.然后需要有一个连线的外观就像是这样 二话不说,百度了一下,找到一个实现, 通道. 把代码拷贝到项目里面,跑了一下,看上去还不错.但是这 ...
- 背水一战 Windows 10 (86) - 文件系统: 获取文件夹的属性, 获取文件夹的缩略图
[源码下载] 背水一战 Windows 10 (86) - 文件系统: 获取文件夹的属性, 获取文件夹的缩略图 作者:webabcd 介绍背水一战 Windows 10 之 文件系统 获取文件夹的属性 ...
- Codeforces Round #499 (Div. 2) C. Fly(数学+思维模拟)
C. Fly time limit per test 1 second memory limit per test 256 megabytes input standard input output ...
- [SRC初探]手持新手卡挖SRC逻辑漏洞心得分享
文章来源i春秋 本文适合新手参阅,大牛笑笑就好了,嘿嘿末尾有彩蛋!!!!!!!!!!!!!!!!!本人参加了本次"i春秋部落守卫者联盟"活动,由于经验不足,首次挖SRC,排名不是那 ...
- Android Studio 配置 androidAnnotations框架详细步骤
第一步:打开app的build.gradle文件 第二步:添加下面红色的部分 apply plugin: 'com.android.application' android { compileSdkV ...
- Java 数组的创建
与C.C++不同,Java在定义数组时并不为数组元素分配内存,因此[ ]中无需指定数组元素的个数,即数组长度. 定义一个数组有两种方式: int[] array; int array[]; 对于如上定 ...
- Java面试集合(二)
前言 大家好,给大家带来Java面试集合(二)的概述,希望你们喜欢 二 1.请问线程有哪些状态? 新建状态(New) 就绪状态(Runnable) 运行状态(Running) 阻塞状态(Blocked ...