最直观的解法,排序之后取下标为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小的数的更多相关文章

  1. 计算序列中第k小的数

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4046399.html 使用分治算法,首先选择随机选择轴值pivot,并使的序列中比pivot ...

  2. ch1_5_2求无序序列中第k小的元素

    import java.util.Arrays; import java.util.PriorityQueue; public class ch1_5_2求无序序列中第k小的元素 { public s ...

  3. [经典算法题]寻找数组中第K大的数的方法总结

    [经典算法题]寻找数组中第K大的数的方法总结 责任编辑:admin 日期:2012-11-26   字体:[大 中 小] 打印复制链接我要评论   今天看算法分析是,看到一个这样的问题,就是在一堆数据 ...

  4. #7 找出数组中第k小的数

    「HW面试题」 [题目] 给定一个整数数组,如何快速地求出该数组中第k小的数.假如数组为[4,0,1,0,2,3],那么第三小的元素是1 [题目分析] 这道题涉及整数列表排序问题,直接使用sort方法 ...

  5. 选择问题(选择数组中第K小的数)

    由排序问题可以引申出选择问题,选择问题就是选择并返回数组中第k小的数,如果把数组全部排好序,在返回第k小的数,也能正确返回,但是这无疑做了很多无用功,由上篇博客中提到的快速排序,稍稍修改下就可以以较小 ...

  6. Leetcode 668.乘法表中第k小的数

    乘法表中第k小的数 几乎每一个人都用 乘法表.但是你能在乘法表中快速找到第k小的数字吗? 给定高度m .宽度n 的一张 m * n的乘法表,以及正整数k,你需要返回表中第k 小的数字. 例 1: 输入 ...

  7. Java实现 LeetCode 668 乘法表中第k小的数(二分)

    668. 乘法表中第k小的数 几乎每一个人都用 乘法表.但是你能在乘法表中快速找到第k小的数字吗? 给定高度m .宽度n 的一张 m * n的乘法表,以及正整数k,你需要返回表中第k 小的数字. 例 ...

  8. 每天一道算法题(32)——输出数组中第k小的数

    1.题目 快速输出第K小的数 2.思路 使用快速排序的思想,递归求解.若键值位置i与k相等,返回.若大于k,则在[start,i-1]中寻找第k大的数.若小于k.则在[i+1,end]中寻找第k+st ...

  9. 寻找数列中第k大的数算法分析

    问题描述:给定一系列数{a1,a2,...,an},这些数无序的,现在求第k大的数. 看到这个问题,首先想到的是先排序,然后直接输出第k大的数,于是得到啦基于排序的算法 算法一: #include&l ...

随机推荐

  1. 剑指offer-顺时针打印矩阵19

    题目描述 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数 ...

  2. Ubuntu—安装并运行sublime

    step1 到官网看看 https://www.sublimetext.com/3 step2 根据版本选择,我的是32位的 step3 ubuntu终端安装 (1)切换目录 -$ cd /opt  ...

  3. [2018 ACL Short and System] 对话系统

    Short Paper(s) 1.  Task-oriented Dialogue System for Automatic Diagnosis. (Cited by 0) Zhongyu Wei, ...

  4. LeetCode 98——验证二叉搜索树

    1. 题目 2. 解答 2.1. 方法一 我们初始化根节点的范围为长整形数据的最小最大值 \([LONG\_MIN,LONG\_MAX]\),则其左子节点的取值范围为 \([LONG\_MIN,根节点 ...

  5. window.open()与window.showModalDialog区别

    window.open()与window.showModalDialog区别 弹出窗口两种方式:    1.window.showModalDialog:      var feature = &qu ...

  6. df -h 卡住

    mount 检查是否有挂载nfs的分区       网络挂载     如果有请umount  -l   /相应目录      umount -l  10.74.82.205:/letv/fet/nfs ...

  7. 如果jsp表单元素的值为空,如何避免null出现在页面上?

    可以写一个简单的函数对空值进行处理,判断值是否为空,如果是空就返回空字符串.实例代码如下: <%! String blanknull(String s) { return (s == null) ...

  8. bootstrap使用中遇到的坑

    一.例如: <div class="form-group"> <label class="control-label col-lg-3"> ...

  9. ubuntu上的inpack测试

    测试linpack 配置 配置linpack环境是整个过程中最麻烦的,也可能是因为我在配置的过程中出现了很多小问题吧.大概有3天的时间除了上课就在配置环境. 问题 总结起来问题和解决方法有这些 1.路 ...

  10. ServletContext域对象

    场景:假设某个web服务,有两个servlet分别是servlet1和servlet2,servlet1要传参数name=zhangsan传送给servlet2,传统方法如下: servlet1端:用 ...