顺序统计:寻找序列中第k小的数
最直观的解法,排序之后取下标为k的值即可。
但是此处采取的方法为类似快速排序分块的方法,利用一个支点将序列分为两个子序列(支点左边的值小于支点的值,支点右边大于等于支点的值)。
如果支点下标等于k,则支点就是查找的值,如果支点的下标大于k,则在左子序列里继续寻找,如果支点下标小于k,则继续在支点右子序列里面继续寻找第(k-支点下标)小的值。
c#实现算法如下:
public class FindSpecialOrderElement<T> where T : IComparable<T>
{
public T FindElementWithOrder(T[] array, int startIndex, int endIndex, int order)
{
int pivot = Partition(array, startIndex, endIndex);
//pivot支点为第(pivot-startIndex+1)小的值
int pivotOrder = pivot - startIndex + ;
if (pivotOrder == order)
{ return array[pivot]; }
else if (pivotOrder > order)
{
return FindElementWithOrder(array, startIndex, pivot - , order);
}
else//pivotOrder < order
{
return FindElementWithOrder(array, pivot + , endIndex, order - pivotOrder);
}
}
public static int Partition(T[] array, int leftIndex, int rightIndex)
{
//leftIndex的位置空出来了
T pivotValue = array[leftIndex];
//将所有<pivotValue的值移动到pivotValue的左边(不稳定排序,因为相等值得相对位置可能被此步骤改变)
//将所有>=pivotValue的值移到右边
//移动的结果就是所有<pivotValue的值都在pivotValue的左边,>=它的都在右边
//记录之后pivotValue所在位置,返回该位置,完成一次分区划分。
while (leftIndex < rightIndex)
{
//因为是leftIndex先空出来位置,所以第一步要从右侧rightIndex向左寻找小于pivotValue的数值位置
while (leftIndex < rightIndex && array[rightIndex].CompareTo(pivotValue) >= ) rightIndex--;
//将找到的小于pivotValue的位置的元素放到空出的leftIndex位置,leftIndex++
if (leftIndex < rightIndex) array[leftIndex++] = array[rightIndex];
//leftIndex向右寻找>=pivotValue的值的位置
while (leftIndex < rightIndex && array[leftIndex].CompareTo(pivotValue) < ) leftIndex++;
//将找到的>=pivotValue的位置的leftIndex元素放到上一步空出的rightIndex位置
//此时leftIndex所在位置变成待插入位置,重新回到外圈循坏的初始状态
if (leftIndex < rightIndex) array[rightIndex--] = array[leftIndex];
}
//最后while循环结束的位置就是leftIndex==rightIndex,并且这个位置是空出来的,正好把pivotValue放到这个位置
//这就是轴的概念,轴两边的值时由轴正好分开的,一边小于轴,一边大于等于轴
array[leftIndex] = pivotValue;
return leftIndex;
} }
方法调用方法:
static void Main(string[] args)
{
FindSpecialOrderElement<int> ESOE = new FindSpecialOrderElement<int>();
int[] data1 = new int[] { , , , , , , , , , };
Console.WriteLine();
data1.ToList<int>().ForEach(i => Console.Write("{0},", i));
int e = ESOE.FindElementWithOrder(data1, , data1.Length - , );
Console.WriteLine("Find the 4th small element:{0}", e); int[] data2 = new int[] { , , , , , , , , , };
Console.WriteLine();
data2.ToList<int>().ForEach(i => Console.Write("{0},", i));
int f = ESOE.FindElementWithOrder(data2, , data1.Length - , );
Console.WriteLine("Find the 7th small element:{0}", f);
Console.ReadKey();
}

作者:Andy Zeng
欢迎任何形式的转载,但请务必注明出处。
http://www.cnblogs.com/andyzeng/p/3695478.html
顺序统计:寻找序列中第k小的数的更多相关文章
- 计算序列中第k小的数
作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4046399.html 使用分治算法,首先选择随机选择轴值pivot,并使的序列中比pivot ...
- ch1_5_2求无序序列中第k小的元素
import java.util.Arrays; import java.util.PriorityQueue; public class ch1_5_2求无序序列中第k小的元素 { public s ...
- [经典算法题]寻找数组中第K大的数的方法总结
[经典算法题]寻找数组中第K大的数的方法总结 责任编辑:admin 日期:2012-11-26 字体:[大 中 小] 打印复制链接我要评论 今天看算法分析是,看到一个这样的问题,就是在一堆数据 ...
- #7 找出数组中第k小的数
「HW面试题」 [题目] 给定一个整数数组,如何快速地求出该数组中第k小的数.假如数组为[4,0,1,0,2,3],那么第三小的元素是1 [题目分析] 这道题涉及整数列表排序问题,直接使用sort方法 ...
- 选择问题(选择数组中第K小的数)
由排序问题可以引申出选择问题,选择问题就是选择并返回数组中第k小的数,如果把数组全部排好序,在返回第k小的数,也能正确返回,但是这无疑做了很多无用功,由上篇博客中提到的快速排序,稍稍修改下就可以以较小 ...
- Leetcode 668.乘法表中第k小的数
乘法表中第k小的数 几乎每一个人都用 乘法表.但是你能在乘法表中快速找到第k小的数字吗? 给定高度m .宽度n 的一张 m * n的乘法表,以及正整数k,你需要返回表中第k 小的数字. 例 1: 输入 ...
- Java实现 LeetCode 668 乘法表中第k小的数(二分)
668. 乘法表中第k小的数 几乎每一个人都用 乘法表.但是你能在乘法表中快速找到第k小的数字吗? 给定高度m .宽度n 的一张 m * n的乘法表,以及正整数k,你需要返回表中第k 小的数字. 例 ...
- 每天一道算法题(32)——输出数组中第k小的数
1.题目 快速输出第K小的数 2.思路 使用快速排序的思想,递归求解.若键值位置i与k相等,返回.若大于k,则在[start,i-1]中寻找第k大的数.若小于k.则在[i+1,end]中寻找第k+st ...
- 寻找数列中第k大的数算法分析
问题描述:给定一系列数{a1,a2,...,an},这些数无序的,现在求第k大的数. 看到这个问题,首先想到的是先排序,然后直接输出第k大的数,于是得到啦基于排序的算法 算法一: #include&l ...
随机推荐
- 利用nohup后台运行jar文件包程序
Linux 运行jar包命令如下: 方式一: java -jar XXX.jar特点:当前ssh窗口被锁定,可按CTRL + C打断程序运行,或直接关闭窗口,程序退出 那如何让窗口不锁定? 方式二 j ...
- 论文笔记:Deep Attentive Tracking via Reciprocative Learning
Deep Attentive Tracking via Reciprocative Learning NIPS18_tracking Type:Tracking-By-Detection 本篇论文地主 ...
- 线性代数之——微分方程和 exp(At)
本节的核心是将常系数微分方程转化为线性代数问题. \[\frac{du}{dt}=\lambda u \quad 的解为 \quad u(t) = Ce^{\lambda t}\] 代入 \(t=0\ ...
- MongoDB3.2 集群搭建
一.集群的理论知识 1.1 集群成员 MongoDB的集群类似于GreenPlum集群,由一个入口节点负责任务分发与结果统计,分片结节负责执行任务.不同GP,多了一个config servers. 集 ...
- 衡量失业:失业率(Unemployment Rate)
定义 劳动力 = 就业人数 + 失业人数 失业率 = (失业人数 / 劳动力) * % 劳动力参与率 = (劳动力 / 成年人口) * %
- 路由器如何设置上网(TP-LINK)
最近宿舍公用的网络一直不太稳定,正赶上毕业季,本来就打算自己买一台自用的路由器,于是我从一个毕业的师姐手里15RMB收了一台路由器,师姐还给了我一根5m的网线和两根全新15m的,感觉光网线就赚翻了. ...
- Word Ladder Problem (DFS + BFS)
Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest t ...
- lintcode-182-删除数字
182-删除数字 给出一个字符串 A, 表示一个 n 位正整数, 删除其中 k 位数字, 使得剩余的数字仍然按照原来的顺序排列产生一个新的正整数. 找到删除 k 个数字之后的最小正整数. N < ...
- js控制input只能输入数字和小数点后两位,输入其他自动清除方法。
工作中input='text'总会遇到要控制输入数字,或者是输入中文,输入电话,输入身份证号,邮箱等.今天我遇到的是要输入数字并且只能小数点后面两位的数字,还不能为负数.废话不多说上代码: <i ...
- alpha阶段个人总结(201521123031林庭亦)
一.个人总结 第一部分:硬的问题 第二部分:软的问题,在成长路上学到了什么? 1 当你看到不靠谱的设计.糟糕的代码.过时的文档和测试用例的时候,不要想 "既然别人的代码已经这样了,我的代码也 ...