分治算法--寻找第k大数
问题描述:给定线性序集中n个元素和一个整数k,1≤k≤n,要求找出这n个元素中第k大的元素,(这里给定的线性集是无序的)。
其实这个问题很简单,直接对线性序列集qsort,再找出第k个即可。但是这样的时间复杂度就是qsort的时间复杂度O(nlogn)。有没有更快的方法呢?看到网上有一种解法是采取了快排的思路,但是稍微坐了些改动,然后时间复杂度能够接近O(n)。因为最近刚刚写了快排的实现,所以在这我就再把这个实现一次吧。
解题思路:与快排不同的是,这里只对划分出来的其中一组进行递归处理。任意选定一个pivotIndex,pivotValue = arr[pivotIndex]。经过一次划分后,pivotValue存储在storeIndex的位置,storeIndex把数组划分为两部分。比pivoteValue大的在前面,比pivotValue小的存储在后面(此时前后两部分是没有排好序的)。那么storeIndex位置的pivotValue就肯定是第storeIndex大的数。然后用K于storeIndex比较,如果K<storeIndex,那么说明第K大一定在右边,那么再对右边进行划分即可。如果K>storeIndex,那么说明第K大一定在左边,那么再对左边进行划分。然后递归,最后就可以得到第K大。
#include <stdio.h> void swap(int *a, int *b)
{
int tmp;
tmp = *a;
*a = *b;
*b = tmp;
} int partition(int arr[], int left, int right, int pivotIndex)
{
int storeIndex = left;
int pivotValue = arr[pivotIndex];
int i; swap(&arr[pivotIndex],&arr[right]); for (i = left; i < right; i ++)
{
if (arr[i] > pivotValue)
{
swap(&arr[i],&arr[storeIndex]);
storeIndex++;
}
}
swap(&arr[storeIndex],&arr[right]);
return storeIndex;
} int findKMax(int arr[], int left, int right, int k)
{
int nRet;
int pivotIndex = left + ; nRet = partition(arr,left,right,pivotIndex);
if (nRet < k)
{
return findKMax(arr,nRet+,right,k);
}
else if (nRet > k)
{
return findKMax(arr,left,nRet-,k);
} return nRet;
} int main()
{
int i,k,nRet;
int arr[] = {,,,,,,,}; scanf("%d",&k);
nRet = findKMax(arr,,,k-); printf("The Kth Max Number locate in %d is :%d\n",nRet,arr[nRet]);
for (i = ; i < ; i++)
{
printf("%3d",arr[i]);
}
return ;
} // :
萧萧空间列出了很多种寻找第K大数的算法。
第二次实现该算法:
#include <stdio.h> void swap(int arr[], int i, int j)
{
int tmp; tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
} int partition(int arr[], int left, int right)
{
int value = arr[left];
int p_insert,p_cmp; swap(arr,left,right);
p_insert = p_cmp = left; while (p_cmp < right)
{
if (arr[p_cmp] < value)
{
swap(arr,p_insert,p_cmp);
p_insert++;
}
p_cmp++;
}
swap(arr,p_insert,right); return p_insert;
} void max_k(int arr[], int left, int right,int k)
{
int ret = partition(arr,left,right);
if (ret == k) return;
else if (ret < k)
ret = partition(arr,ret+,right);
else
ret = partition(arr,left,ret);
} int main()
{
int arr[] = {,,,,,,,,};
int i,k = ; max_k(arr,,,k); for (i = ; i < k; i++)
{
printf("%d ",arr[i]);
}
printf("\n"); return ;
} // :
分治算法--寻找第k大数的更多相关文章
- 蓝桥杯 算法训练 区间k大数查询(水题)
算法训练 区间k大数查询 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示序列长度. ...
- 算法训练 区间k大数查询
http://lx.lanqiao.org/problem.page?gpid=T11 算法训练 区间k大数查询 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个 ...
- 蓝桥杯--算法训练 区间k大数查询
算法训练 区间k大数查询 时间限制:1.0 ...
- 算法训练 区间K大数
算法训练 区间k大数查询 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示序列长度. ...
- 蓝桥杯算法训练 区间k大数查询
算法训练 区间k大数查询 问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示序列长度. 第二行包含n个正整数,表示给定的序列. 第三个 ...
- P3290 寻找第K大数
描述 寻找第K大数 N个小朋友在一起做游戏.每个小朋友在自己的硬纸板上写一个数,然后同时举起来.接着,小y老师提一个问题,看哪个小朋友先抢答出来.问题是:在这N个数中,第K大的是哪个数?请你编程完成. ...
- Java实现 蓝桥杯 算法训练 区间k大数
算法训练 区间k大数查询 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示序列长度. 第二 ...
- 算法准备-分治算法解决第k位数的线性查找
由作业士兵排队问题引出的 在一个划分成网格的操场上,n个士兵散乱地站在网格点上.网格点由整数最表(x,y)表示.士兵可以沿着网格边上.下.左.右移动一步,但在同一时刻一个网格上只能有一名士兵.按照军官 ...
- 蓝桥网试题 java 算法训练 区间k大数查询
-------------------------------------------------------------------------- 数组也有sort方法 尽量把输入和操作分开写 -- ...
随机推荐
- mysql打开binlog
修改mysql的配置文件,ubuntu下mysql的配置文件存放位置为:/etc/mysql/my.cnf 找到log_bin配置项,指定一个路径: 重启数据库:/etc/init.d/mysql r ...
- ELK logstash邮件报警
这个方法有一个问题就是我这边不能给我们公司的邮箱发邮件.还有就是我们有两个邮箱一个是腾讯企业邮箱,还有一个就是我们的集团邮箱 使用下面的这个方法是不能给我们的集团邮箱发邮件的.第二个问题就是这个方法给 ...
- JAXB--@XmlType注解标注xml生成顺序
默认情况下,Jaxb编组出来的xml中的字段顺序是随机的,你可以使用@XmlType的propOrder属性 来指定序列化的顺序. 第一步:定义java类时,使用@XmlType(propOrde ...
- Android开源之BaseRecyclerViewAdapterHelper(持续更新!)
官方地址:http://www.recyclerview.org/ 文档 v1.9.8 English 中文 v2.0.0 English 中文 Extension library PinnedSec ...
- Android 关于Fragment一些简单注意事项
1.Fragment的生命周期一定要了解清楚: 其实没有什么好说的. 注意关键字所执行的方法: 注意下面基本fragmentTransaction.replace();运行 当FragmentA(初始 ...
- android 圆角编写(懒得去找,写给自己看的)
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="r ...
- [转载]关于generate用法的总结【Verilog】
转载自http://www.cnblogs.com/nanoty/archive/2012/11/13/2768933.html Abtract generate语句允许细化时间(Elaboratio ...
- scrollReveal.js页面滚动动态效果
scrollReveal.jshttp://www.dowebok.com/134.html简介 和 WOW.js 一样,scrollReveal.js 也是一款页面滚动显示动画的 JavaScrip ...
- OpenMP基础使用
OpenMP是CPU并行加速相关的编译处理方案,VS非常早的版本号就对其提供了支持,只是默认是关闭的.要开启这一支持.仅仅须要在项目的属性中设置就能够,详细选项为:配置属性->C/C++-> ...
- c++ STL map 结构体
Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,由于这个特性,它完成有可能在我们处理一对一数据的时候 ...