给定两个有序数组arr1和arr2,在给定一个整数k,返回两个数组的所有数中第K小的数。
例如:
arr1 = {1,2,3,4,5};
arr2 = {3,4,5};
K = 1;
因为1为所有数中最小的,所以返回1;

arr1 = {1,2,3};
arr2 = {3,4,5,6};
K = 4;
因为3为所有数中第4小的数,所以返回3;

要求:如果arr1的长度为N,arr2的长度为M,时间复杂度请达到O(log(min{M,N}))。

这题目的难度在于时间复杂度请达到O(log(min{M,N})),参考http://www.cnblogs.com/diegodu/p/3790860.html可以达到O(log(M+N))

借助http://www.cnblogs.com/diegodu/p/4589847.html 求等长数组求中位数的方法能够实现。

举例,

arr1  1 ~ 10,

arr2  1‘ ~ 20’.

当kth = 7时,kth < min(s1,s2),

  求两个数组的前K个元素的中位数即可,因为,第K个必然在两个数组的前K个元素中。

  getUpMedian(arr1, 0, kth - 1, arr2, 0, kth - 1);

当kth = 26时,kth>max(s1,s2)

  arr1 的1到5 是不可能的,就算5>20,也不过第25而已,不会是26.

   arr2的 1’到15‘ 是不可能的,就算15’>10,也不过第25而已,不会是26.

  所以排除了5+15个元素,arr1剩下5个,arr2剩下5个。

  如果求剩下10个元素的上中位数,我们能得到第25大的,不是第26大,

所以,我们可以单独检验一下arr1 的6 和arr2的16‘是不是答案,

若是直接返回,不是的话又排除了两个,排除了22个,剩余8个,求上中位数第四个,加一起正好是第26个。

当kth = 16时,min(s1, s2)<kth<max(s1,s2)

arr1 无法排除,都有可能。

arr2的 1’~5‘排除,就算5’大于arr1的10,也不过是15。

arr2的 17‘~20’排除,17‘本来就排17了,最小也就是拍17。

所以arr2还剩下 6’ ~ 16‘ 11个元素,而arr1 有10个元素,

为了使用上中位数的算法,可以单独检测一下6’,若是返回,若不是淘汰,剩余的使用上中位数的算法。

http://www.nowcoder.com/profile/864393/test/231563/24588

class Solution {
public:
int getUpMedian(vector<int> arr1, vector<int> arr2) { if(arr1.size() != arr2.size())
return -;
if(arr1.size() == )
return -; return getUpMedian(arr1, , arr1.size() -,
arr2, , arr1.size() - );
} int getUpMedian(const vector<int> & arr1, int start1, int end1,
const vector<int> & arr2, int start2, int end2)
{
//cout << "start1\t" << start1 << endl;
//cout << "end1\t" << end1 << endl;
//cout << "start2\t" << start2 << endl;
//cout << "end2\t" << end2 << endl; if(start1 == end1)
{
return min(arr1[start1], arr2[start2]);
} int size = end1 - start1 + ;
int halfSize;
if(size & 0x1 == 0x1)
{
halfSize = (size + )/;
}
else
{
halfSize = size/;
} if(arr1[start1 + halfSize - ] == arr2[start2 + halfSize - ])
return arr1[start1 + halfSize - ];
else if(arr1[start1 + halfSize - ] > arr2[start2 + halfSize - ])
return getUpMedian(arr1, start1, start1 + halfSize - ,
arr2, end2-(halfSize-), end2);
else //if(arr1[start1 + halfSize - 1] > arr2[start2 + halfSize - 1])
return getUpMedian(arr1, end1-(halfSize-) , end1,
arr2, start2, start2 + halfSize -);
} int findKthNum(vector<int> arr1, vector<int> arr2, int kth)
{
int size1 = arr1.size();
int size2 = arr2.size(); if(size1 > size2)
return findKthNum(arr2, arr1, kth);//ensure size1 < size2 if(kth <= size1)
return getUpMedian(arr1, , kth - , arr2, , kth - );
else if (kth <= size2 && kth > size1)
//i.e.s1 = 10, s2 = 20, kth = 14;
// for arr2, kth + 1 ~ size2(15 ~ 20) is impossibly answer
// for arr2, 1 ~ kth - size1 -1 (1 ~ 3) is impossibly answer
// so arr2 has 20 - 6 - 3 = 11 numbers, but arr1 has 10 numbers
// so jundge one element of arr2 firstly, the call getUpMedian
{
if(arr2[kth - size1 - ] >= arr1[size1 - ] )
return arr2[kth - size1 - ];
return getUpMedian(arr1, , size1-, arr2, kth-size1, kth-);
} else //if (kth > size2)
//i.e.s1 = 10, s2 = 20, kth = 25;
// first 4(kth - s2 - 1) of arr1 is impossibly answer. so just remove them
// first 14(kth - s1 - 1) of arr2 is impossibly answer.so just remvoe them
// arr1 still has s1 - (kth - s2 - 1) = s1 + s2 - kth + 1 numbers (6)
// arr2 still has s2 - (kth - s1 - 1) = s1 + s2 - kth + 1 numbers (6)
// we removes 2 * kth - s1 - s2 -2 numbers, (18)
// now we junge if arr1[kth-s2-1] and arr2[kth-s1-1] is the answer,if not, we remother them
// then we removes 2 * kth - s1 - s2 numbers (20)
// and arr1 and arr2 both have s1 + s2 - kth numbers(5)
// we just calc upMedia of them and got the answer, 20 + 5 = 25
{
if(arr2[kth-size1-] >= arr1[size1-])
return arr2[kth-size1-];
if(arr1[kth-size2-] >= arr2[size2-])
return arr1[kth-size2-];
return getUpMedian(arr1, kth-size2, size1-, arr2, kth-size1, size2-);
} }
};

[nowCoder] 两个不等长数组求第K大数的更多相关文章

  1. poj 2985 The k-th Largest Group 树状数组求第K大

    The k-th Largest Group Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 8353   Accepted ...

  2. 无序数组求第K大的数

    问题描述 无序数组求第K大的数,其中K从1开始算. 例如:[0,3,1,8,5,2]这个数组,第2大的数是5 OJ可参考:LeetCode_0215_KthLargestElementInAnArra ...

  3. 树状数组求第k小的元素

    int find_kth(int k) { int ans = 0,cnt = 0; for (int i = 20;i >= 0;i--) //这里的20适当的取值,与MAX_VAL有关,一般 ...

  4. hdu 4217 Data Structure? 树状数组求第K小

    Data Structure? Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  5. HDU 5249 离线树状数组求第k大+离散化

    KPI Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  6. 寻找数组中第K大数

    1.寻找数组中的第二大数 using System; using System.Collections.Generic; using System.Linq; using System.Text; u ...

  7. 求第K大数(分治)

    题意:已知N个数,求第K大数. 分析: 1.复杂度O(n). 2.利用快排中划分的原理,每次划分以序列中第一个数x为标准,将序列划分为{比x大的数}x{比x小的数}. 3.若集合{比x大的数}中元素为 ...

  8. poj3261 后缀数组求重复k次可重叠的子串的最长长度

    Milk Patterns Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 13669   Accepted: 6041 Ca ...

  9. 计算两个有序数组的第K大数(转)

    传统解法,最直观的解法是O(m+n).直接merge两个数组,然后求第K大的数字. 如果想要时间复杂度将为O(log(m+n)).我们可以考虑从K入手.如果我们每次能够删除一个一定在第K个元素之前的元 ...

随机推荐

  1. Coarse-Grained lock 粗粒度锁

    用一个锁Lock一组相关的对象 有时,需要按组来修改多个对象. 这样,在需要锁住其中一个的时候,必须连带地将其他的对象都上锁. 为每一个对象都加上一个锁是很繁琐的. 粗粒度锁是覆盖多个对象的单个锁. ...

  2. Assembly(程序集) 反射和缓存

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  3. 另辟思路解决 Android 4.0.4 不能监听Home键的问题

    问题描述: 自从Android 4.0以后,开发人员是不能监听和屏蔽Home键的,对于KEYCODE_HOME,官方给出的描述如下: Home key. This key is handled by ...

  4. asp.net多图片上传实现程序代码

    下面是一个完整的asp.net同时支持多图片上传一个实现,有需要的朋友可参考一下,本文章限制同时可上传8张图片,当然大可自己可修改更多或更少. 前台代码如下: 复制代码代码如下: <% @ Pa ...

  5. 修改Win7远程桌面端口

    Win7与XP不同,在开启远程桌面修改端口后是无法直接访问的,原因是还未修改远程桌面在防火墙入站规则中的端口号. 修改远程桌面端口: [HKEY_LOCAL_MACHINE/SYSTEM/Curren ...

  6. php + apache + mysql环境搭建

    别人写的很好,若是不改变php默认访问路径的话,能够成功搭建是没问题的 http://www.cnblogs.com/pharen/archive/2012/02/06/2340628.html

  7. Linux&UNIX上卸载GoldenGate的方法

    1. Log on to the database server (as oracle) where the GoldenGate software is installed. [root@oracl ...

  8. WPF与DevExpress之旅-序言

    随着.NET技术的发展,从之前的WINFORM转向到WPF是我们技术改革的必然趋势.WPF能给人带来震撼的视觉体验,也能更加规范我们的开发模式,与传统的WINFORM开发来说具有革命性的意义.DevE ...

  9. hadoop启动后jps 没有namenode

      hadoop集群启动后,jps 发现没有namenode. 网上查了下,这问题可能是由于两次或两次以上格式化NameNode造成的. 因为我的是刚刚新搭建的集群,里面没什么资料,所以我直接删除各个 ...

  10. iOS定位服务编程详解

    现在的移动设备很多都提供定位服务,使用iOS系统的iPhone.iPod Touch和iPad都可以提供位置服务,iOS设备能提供3种不同途径进行定位:Wifi, 蜂窝式移动电话基站, GPS卫星 i ...