计算两个有序数组的第K大数(转)
传统解法,最直观的解法是O(m+n)。直接merge两个数组,然后求第K大的数字。
如果想要时间复杂度将为O(log(m+n))。我们可以考虑从K入手。如果我们每次能够删除一个一定在第K个元素之前的元素,那么我们需要进行K次,但是如果每次我们都删除一半呢?由于两个数组都是有序的,我们应该充分利用这个信息。
- 假设A B 两数组的元素都大于K/2,我们将A B两数组的第K/2个元素进行比较。比较的结果有三种情况。
- A[K/2] == B[K/2]
- A[K/2] > B[K/2]
- A[K/2] <= B[K/2]
- 如果 A[K/2] < B[K/2] 意味着 A[0] 到 A[K/2] 肯定在A∪B的前k个元素中。因此我们可以放心删除A数组的这个k/2个元素。同理A[K/2] > B[K/2]。
- 如果 A[K/2] == B[K/2] 说明已经找到了第K个元素,直接返回A[K/2]或者B[K/2]。
- 假设A B 两数组的元素都大于K/2,我们将A B两数组的第K/2个元素进行比较。比较的结果有三种情况。
代码如下
int find_kth(int A[],int m, int B[], int n, int k){
if(m > n )
return find_kth(B, n, A, m, k);
if( m == )
return B[k-];
if( k == )
return min(A[], B[]); int ia = min(k /, m);
int ib = k -ia;
if( A[ia-] < B[ib -]){
return find_kth(A +ia, m -ia, B, n, k -ia);
}else if( A[ia-] > B[ib-]){
return find_kth(A, m, B +ib, n -ib, k -ib);
}else
return A[ia-];
}说明
- 注意其中的递归终止条件。
- 将求第K大元素的问题划分成为子问题,不断的对问题进行缩小,采取递归的方式求解。
- 此问题可以进行拓展,比如求两有序数组的中位数。
转自:http://www.cnblogs.com/swanspouse/p/5285015.html
计算两个有序数组的第K大数(转)的更多相关文章
- 【递归打卡2】求两个有序数组的第K小数
[题目] 给定两个有序数组arr1和arr2,已知两个数组的长度分别为 m1 和 m2,求两个数组中的第 K 小数.要求时间复杂度O(log(m1 + m2)). [举例] 例如 arr1 = [1, ...
- 两个有序数组的第n大数
两个有序数组,各自含有n个元素,求第n大的元素 1.顺序遍历两个数组,计数变量k统计出现的第k小元素,时间复杂度为O(n) 代码例如以下: int getmid(int a[],int b[],int ...
- (算法)两个有序数组的第k大的数
题目: 有两个数组A和B,假设A和B已经有序(从大到小),求A和B数组中所有数的第K大. 思路: 1.如果k为2的次幂,且A,B 的大小都大于k,那么 考虑A的前k/2个数和B的前k/2个数, 如果A ...
- [LeetCode]Median of Two Sorted Arrays 二分查找两个有序数组的第k数(中位数)
二分.情况讨论 因为数组有序,所以能够考虑用二分.通过二分剔除掉肯定不是第k位数的区间.如果数组A和B当前处理的下标各自是mid1和mid2.则 1.假设A[mid1]<B[mid2], ①.若 ...
- 【medium】4. Median of Two Sorted Arrays 两个有序数组中第k小的数
There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two ...
- 求两个有序数组的中位数或者第k小元素
问题:两个已经排好序的数组,找出两个数组合并后的中位数(如果两个数组的元素数目是偶数,返回上中位数). 设两个数组分别是vec1和vec2,元素数目分别是n1.n2. 算法1:最简单的办法就是把两个数 ...
- leetcode题目4.寻找两个有序数组的中位数(困难)
题目描述: 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)). 你可以假设 nums1 和 ...
- 两个有序数列找第k小
给定一个数组,数组中的数据无序,在一个数组中找出其第k个最小的数,例如对于数组x,x = {3,2,1,4,5,6},则其第2个最小的数为2 两个有序数组 找第k小 * 方案一 合并遍历 * 二:游 ...
- 选取两个有序数组中最大的K个值,降序存入另一个数组中
原题: 假设有两个有序的整型数组int *a1, int *a2,长度分别为m和n.试用C语言写出一个函数选取两个数组中最大的K个值(K可能大于m+n)写到int *a3中,保持a3降序,并返回a3实 ...
随机推荐
- xen 保存快照的实现之 —— device model 状态保存
xen 保存快照的实现之 —— device model 状态保存 实现要点: 设备状态保存在 /var/lib/xen/qemu-save.x 文件这个文件由 qemu-dm 产生,也由 qemu- ...
- 用RegisterHotKey注册系统热键
函数功能:该函数定义一个系统范围的热键. 函数原型:BOOL RegisterHotKey(HWND hWnd,int id,UINT fsModifiers,UINT vk): 参数: hWnd:接 ...
- 在C#中将金额转换成中文大写金额
具体代码如下: /// <summary> /// 金额转换成中文大写金额 /// </summary> /// <param name="LowerMoney ...
- Ubuntu14.04配置VIM与GVIM 高亮、跳转与变量函数列表
一.环境:刚安装好的Ubuntu14.04,本文只能保证 在Ubuntu下能达到效果. 二.安装GVim. sudo apt-get update sudo apt-get install vim-g ...
- hiho一下第131周 后缀自动机二·重复旋律8(循环相似子串)
后缀自动机五·重复旋律8 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一段音乐旋律可以被表示为一段数构成的数列. 小Hi ...
- 一个错误使用单例模式的场景及ThreadLocal简析
近来参与一个Java的web办公系统,碰到一个bug,开始猜测是线程池管理的问题,最后发现是单例模式的问题. 即,当同时发起两个事务请求时,当一个事务完成后,另一个事务会抛出session is cl ...
- 2.2多线程(java学习笔记)线程状态及线程操作的相关方法
一.线程的状态 线程一般具有五种状态,即创建.就绪.运行.阻塞.终止. 它们之间的关系: 二.线程操作相关方法 1.设置和取得线程名称. 如果不设置线程名称,系统会自动分配线程名,一般格式为Threa ...
- Android 更新UI的两种方法——handler和runOnUiThread()
今天看到了一个runOnUiThread()方法用来更新UI,觉得很神奇!! 方法一:handler机制不说了. 方法二:利用Activity.runOnUiThread(Runnable)把更新ui ...
- Android SDK 目录说明
Android SDK目录说明: AVD Manager.exe:虚拟机管理工具 SDK Manager.exe:sdk管理工具 tools目录:包括测试.调试.第三方工具.模拟器.数据管理工具等. ...
- js封装的一行半显示省略号。(字数自由控制)
$(function() { //控制一行半隐藏 (function ($) { $.fn.displayPart = function (opts) { $(this).each(function ...