最快效率求出乱序数组中第k小的数
题目:以尽量高的效率求出一个乱序数组中按数值顺序的第k 的元素值
思路:这里很容易想到直接排序然后顺序查找,可以使用效率较高的快排,但是它的时间复杂度是O(nlgn),我们这里可以用一种简便的方法,不一定需要排序,使用快速排序中双向分区的扫描方法,这里使用的是优化过后的三点中值法,具体思想一样,只是主元的取法不一样。然后扫描出主元下标,然后根据主元的值将数组划分成一半大,一半小。然后再根据主元下标与k进行比较,如果相等,说明主元就是我们要找的数,如果大于k,说明k所代表的值在小的那边,继续向小的那部分递归,如果小于k,说明k代表的值在大的那边,继续向大的那部分递归。这样即可得出正确答案。这种方法的时间复杂度为O(n),因为每次递归都相当于舍弃掉了差不多一半的数。
代码:
import java.util.Arrays;
public class SelectK {
public static void main(String[] args) {
int arr[] = new int[10];
for(int i=0;i<10;i++){
arr[i] = (int) ((Math.random()+1)*10);
}
System.out.println("查找前数组:"+Arrays.toString(arr));
int k = selectK(arr, 0, arr.length-1, 5);
System.out.println("查找出第k小的元素:"+k);
}
/**
*
* @param arr
* @param p 开始下标
* @param r 结束下标
* @param k 求第k小元素 (递增第k个元素)
* @return
*/
public static int selectK(int[] arr,int p,int r,int k){
int q = partition(arr, p, r); // 主元的下标
int qk = q - p + 1; // 主元是第几个元素
if (qk==k) {
return arr[q];
}else if (qk>k) {
return selectK(arr, p, q-1, k);
}else {
return selectK(arr, q+1, r, k-qk);
}
}
//三点中值法
public static int partition(int[] arr, int p, int r) {
//优化,在p, r, mid之间,选一个中间值作为主元
int midIndex = p + ((r - p) >> 1);//中间下标
int midValueIndex = -1;//中值的下标
if(arr[p] <= arr[midIndex] && arr[p] >= arr[r]) {
midValueIndex = p;
}else if(arr[r] <= arr[midIndex] && arr[r] >= arr[p]) {
midValueIndex = r;
}else {
midValueIndex = midIndex;
}
swap(arr, p, midValueIndex);
int pivot = arr[p];
int left = p + 1; //左侧指针
int right = r; //右侧指针
while(left <= right) {
while(left <= right && arr[left] <= pivot) {
left++;
}
while(left <= right && arr[right] > pivot) {
right--;
}
if(left < right) {
swap(arr, left, right);
}
}
swap(arr, p, right);
return right;
}
private static void swap(int[] A, int p, int bigger) {
int temp = A[p];
A[p] = A[bigger];
A[bigger] = temp;
}
}
结果:

最快效率求出乱序数组中第k小的数的更多相关文章
- 乱序数组中第k大的数(顺序统计量)
该问题是顺序统计量中十分经典的问题. 使用快排中的分区法,将第k大的数排序.若双向扫描分区加上三点中值法或绝对中值法,可以保证在 O(n) 时间里找出第k大的数. 补充:可以直接使用C++STL中的n ...
- #7 找出数组中第k小的数
「HW面试题」 [题目] 给定一个整数数组,如何快速地求出该数组中第k小的数.假如数组为[4,0,1,0,2,3],那么第三小的元素是1 [题目分析] 这道题涉及整数列表排序问题,直接使用sort方法 ...
- 求一个数组中第K小的数
面试南大夏令营的同学说被问到了这个问题,我的第一反应是建小顶堆,但是据他说用的是快排的方法说是O(n)的时间复杂度, 但是后来经过我的考证,这个算法在最坏的情况下是O(n^2)的,但是使用堆在一般情况 ...
- 找出数组[1...n]中第k小元素
//问题描述: 试编写一个算法,使之能够在数组L[1...n]中找出第k小的元素(即从小到大排序后处于第k个位置的元素) #include <stdio.h> // 结合快排思想,查找第5 ...
- 求第k小的数
题目链接:第k个数 题意:求n个数中第k小的数 题解: //由快速排序算法演变而来的快速选择算法 #include<iostream> using namespace std; const ...
- sort(()=>{return Math.random()-0.5)}乱序数组不准确
为什么sort(()=>{return Math.random()-0.5)}乱序数组不准确.(注意结合插入排序原理来理解) @1.chrome浏览器对于数组长度10以内为插入排序.反之则快速排 ...
- 寻找两个已序数组中的第k大元素
寻找两个已序数组中的第k大元素 1.问题描述 给定两个数组与,其大小分别为.,假定它们都是已按照增序排序的数组,我们用尽可能快的方法去求两个数组合并后第大的元素,其中,.例如,对于数组,.我们记第大的 ...
- C语言:找出一个大于给定整数m且紧随m的素数,-求出能整除x且不是偶数的数的个数,
//函数fun功能:找出一个大于给定整数m且紧随m的素数,并作为函数值返回. #include <stdlib.h> #include <conio.h> #include & ...
- 找出整数中第k大的数
一 问题描述: 找出 m 个整数中第 k(0<k<m+1)大的整数. 二 举例: 假设有 12 个整数:data[1, 4, -1, -4, 9, 8, 0, 3, -8, 11, 2 ...
随机推荐
- jQuery基础操作
1.jQuery的介绍 jQuery是一个轻量级的.兼容多浏览器的JavaScript库.jQuery使用户能够更方便地处理HTML Document.Events.实现动画效果.方便地进行Ajax交 ...
- ProgressDialog替代
在API level 26 中,ProgressDialog被声明不赞成使用,应使用的替代方法是ProgressBar 利用下列代码实现ProgressBar的出现和消失 progressBar.se ...
- python单元测试框架unittest总结
unittest.TestCase:TestCase类,所有测试用例类继承的基本类. class BaiduTest(unittest.TestCase): TestCase类的属性如下: setUp ...
- Linux telnet安装
为什么需要telnet? telnet就是查看某个端口是否可访问.我们在搞开发的时候,经常要用的端口就是 8080.那么你可以启动服务器,用telnet 去查看这个端口是否可用. Linux cent ...
- OpenCV-Python:Harris角点检测与Shi-Tomasi角点检测
一.Harris角点检测 原理: 角点特性:向任何方向移动变换都很大. Chris_Harris 和 Mike_Stephens 早在 1988 年的文章<A CombinedCorner an ...
- 使用With递归查询 树
UNION ALL -- 递归成员 SELECT a.* FROM tree a JOIN CTE c ON a.pid = c.id ) SELECT * from CTE --1.将 CTE ...
- 2018-2019-2 20165239其米仁增《网络对抗》Exp1 PC平台逆向破解
一.实验内容 1.掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码(0.5分) 2.掌握反汇编与十六进制编程器 (0.5分) 3.能正确修改机器指令改变程序执行流程(0.5分) 4.能 ...
- 《团队作业》五小福团队--UNO的博客链接汇总
<团队作业>五小福团队--UNO的博客链接汇总 <团队作业第一周>五小福团队作业--UNO <团队作业第二周>五小福团队作业--UNO <团队作业第三.第四周 ...
- 八、OpenStack—Cinder组件安装
一.安装和配置控制器节点 1.先决条件 1)创建数据库 # mysql -u root -p 2)创建cinder数据库 MariaDB [(none)]> CREATE DATABASE ci ...
- StackExchange.Redis超时的问题
最近公司有个项目,在请求量大的情况下,有大量的错误日志是关于redis超时的问题: Timeout performing SET XXX, inst: 27, mgr: ProcessReadQueu ...