转载博客:http://www.cnblogs.com/buptLizer/archive/2012/03/31/2427579.html

题目意思:给出两个排好序的数组 ,不妨设为a,b都按升序排列,及k的值,求出第k大的那个元素。

分析这个题目,如果题目没有时间复杂度的要求,我们可以定义两个指针i,j分别指向a,b,如果a[i]<b[j]则i++否则

j++,这个记录下走了多少步,如果==k步,则找到了第k大的元素,复杂度为O(k).

那么如果有复杂度的要求,要求为O(log(len_a+len_b))呢,这个就得好好考虑,怎么利用二分来解决这个问题。

解法一:

假如第k大的数在a中,设置a[mid],那么肯定有b[k-mid-1]<=a[mid]<=b[k-mid],这是由于a中已经有mid个元素<a[mid]了,

则b中肯定还有k-mid - 1个元素小于a[mid],所以我们判断

若b[k-mid-2]<=a[mid]<=b[k-mid-1], 返回a[mid]

若a[mid] < b[k-mid-2] 说明a[mid]小于第k个元素值,a.low = a.mid + 1

若a[mid] > b[k-mid-1],说明a[mid]大于第k个元素值,a.high = a.mid - 1

结束条件为a.low > a.high 如果未找到,则假设存在于b中,再判断一次

代码如下:

int get_k_from_sorted_array(int* a, int* b, int low, int high, int k, int len)
{
if(low > high)
return -1;
int mid = low + (high - low)/2;
//a中元素个数小于k个,那么k - 2 - mid就可能超出b的下标范围
if(k - 2 - mid >= len)
return get_k_from_sorted_array(a, b, mid + 1, high, k, len);
if(k - 1 - mid < len)
{
//判断b数据中是否存在b[k-1-mid]
if(a[mid] >= b[k - mid - 2] && a[mid] <= b[k - mid - 1])
return a[mid];
}
else
{
if(a[mid] >= b[k - mid - 2])
return a[mid];
}
if(a[mid] < b[k - mid - 2])
return get_k_from_sorted_array(a, b, mid + 1, high, k, len);
return get_k_from_sorted_array(a, b, low, mid - 1, k, len);
}
int _func(int* a, int a_len, int* b, int b_len, int k)
{
int rst = 0;
if(a_len + b_len + 2 < k)
return -1;
int p1 = a_len > k - 1 ? k - 1: a_len;
int p2 = b_len > k - 1 ? k - 1: b_len;
rst = get_k_from_sorted_array(a, b, 0, p1, k, 4);
if(-1 == rst)
{
rst = get_k_from_sorted_array(b, a, 0, p2, k, 5);
}
return rst;
}

解法二:

判断a[mid_a] 与 b[mid_b]的关系
 如果a[mida] < b[mid_b]

1)k小于等于mida + midb + 1,那么b数组从mid_b开始就没有用了,缩小b的搜索范围
 2)k大于mida + midb + 1, 那么a数组从low到mid_a开始就没用了,缩小a的搜索范围
 3)终止条件是 a搜索完 返回b中元素或者相反

代码如下:

int get_k_from_sorted_array2(int* a, int*b, int la, int ha, int lb, int hb, int k)
{
if(la > ha)
return b[lb + k - 1];
if(lb > hb)
return a[la + k - 1];
int mida = (la + ha)>>1;
int midb = (lb + hb)>>1;
int num = mida- la + midb - lb + 1;
cout<<la<<" "<<ha<<" "<<lb<<" "<<hb<<" "<<num<<" "<<a[mida]<<" "<<b[midb]<<endl; if(a[mida] <= b[midb])
{
if(k <= num)
return get_k_from_sorted_array2(a, b, la, ha, lb, midb - 1, k);
else
return get_k_from_sorted_array2(a, b, mida + 1, ha, lb, hb, k - (mida - la + 1));
}
else
{
if(k <= num)
return get_k_from_sorted_array2(a, b, la, mida - 1, lb, hb, k);
else
return get_k_from_sorted_array2(a, b, la, ha, midb + 1, hb, k - (midb - lb + 1));
}
}
int _func2(int* a, int a_len, int* b, int b_len, int k)
{
int rst = 0;
if(a_len + b_len < k)
return -1;
int p1 = a_len > k ? k : a_len;
int p2 = b_len > k ? k : b_len;
cout<<p1<<" "<<p2<<endl;
rst = get_k_from_sorted_array2(a, b, 0, p1 - 1, 0, p2 - 1, k);
return rst;
}

认真对待每一道算法题 之 两个排序好的数组寻找的第k个大的数的更多相关文章

  1. 每天一道算法题(4)——O(1)时间内删除链表节点

    1.思路 假设链表......---A--B--C--D....,要删除B.一般的做法是遍历链表并记录前驱节点,修改指针,时间为O(n).删除节点的实质为更改后驱指针指向.这里,复制C的内容至B(此时 ...

  2. java:合并两个排序的整数数组A和B变成一个新的数组。新数组也要有序。

    合并两个排序的整数数组A和B变成一个新的数组.新数组也要有序. 样例 1: 输入: A=[1], B=[1] 输出:[1,1] 样例解释: 返回合并后的数组. 样例 2: 输入: A=[1,2,3,4 ...

  3. 9.11排序与查找(一)——给定两个排序后的数组A和B,当中A的末端有足够的缓冲空间容纳B。将B合并入A并排序

    /**  * 功能:给定两个排序后的数组A和B,当中A的末端有足够的缓冲空间容纳B.将B合并入A并排序. */ /** * 问题:假设将元素插入数组A的前端,就必须将原有的元素向后移动,以腾出空间. ...

  4. 从一道算法题实现一个文本diff小工具

    众所周知,很多社区都是有内容审核机制的,除了第一次发布,后续的修改也需要审核,最粗暴的方式当然是从头再看一遍,但是编辑肯定想弄死你,显然这样效率比较低,比如就改了一个错别字,再看几遍可能也看不出来,所 ...

  5. 【每天一道算法题】时间复杂度为O(n)的排序

    有1,2,……一直到n的无序数组,求排序算法,并且要求时间复杂度为O(n),空间复杂度为O(1),使用交换,而且一次只能交换两个数. 这个是以前看到的算法题,题目不难.但是要求比较多,排序算法中,时间 ...

  6. 提前批笔试一道算法题的Java实现

    题目描述 这是2021广联达校招提前批笔试算法题之一. 我们希望一个序列中的元素是各不相同的,但是理想和显示往往是有差距的.现在给出一个序列A,其中难免有相同的元素,现在提供了一种变化方式,使得经过若 ...

  7. 每天一道算法题(14)——N个降序数组,找到最大的K个数

     题目: 假定有20个有序数组,每个数组有500个数字,降序排列,数字类型32位uint数值,现在需要取出这10000个数字中最大的500个. 思路 (1).建立大顶堆,维度为数组的个数,这里为20( ...

  8. 每天一道算法题-leetcode136-只出现一次的数字

    前言 打卡第一天 2019.10.26日打卡 算法,即解决问题的方法.同一个问题,使用不同的算法,虽然得到的结果相同,但是耗费的时间和资源是不同的.这就需要我们学习算法,找出哪个算法更好. 大家都知道 ...

  9. 一道算法题加深我对C++中map函数的理解

    一.一道题目引发我对map函数的考量 首先是题目大意:有n个银行,a[i]表示这个人在第i个银行有a[i]块钱(可以是负数),所有银行的钱加起来正好是0.每次只能在相邻的银行之间转账,问最少要转多少次 ...

随机推荐

  1. 各大互联网公司2014前端笔试面试题–JavaScript篇

    很多面试题是我自己面试BAT亲身经历碰到的.整理分享出来希望更多的前端er共同进步吧,不仅适用于求职者,对于巩固复习js更是大有裨益. 而更多的题目是我一路以来收集的,也有往年的,答案不确保一定正确, ...

  2. 初识Ildasm.exe——IL反编译的实用工具

    原文地址:http://www.cnblogs.com/yangmingming/archive/2010/02/03/1662307.html Ildasm.exe 概要: 一.前言: 微软的IL反 ...

  3. hdu----(4513)吉哥系列故事——完美队形II(manacher(最长回文串算法))

    吉哥系列故事——完美队形II Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)To ...

  4. 南阳OJ----Binary String Matching

    Binary String Matching 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 Given two strings A and B, whose alp ...

  5. log4j配置文件的详解

    1.配置根Logger,其语法为: log4j.rootLogger = [ level ] , appenderName, appenderName, … 其中,level 是日志记录的优先级,分为 ...

  6. java作业——整数相加

    设计思路:由于命令行参数都是字符串,所以解决问题的关键在于字符串和整数之间的转化.首先定义数组,让所要相加的数组成一个数组,然后实现数组的字符串转化为整数,最后相加输出就行了. 程序流程图: 源代码: ...

  7. jquery改变元素的值的函数text(),html(),val()

    text() - 设置或返回所选元素的文本内容 html() - 设置或返回所选元素的内容(包括 HTML 标记) val() - 设置或返回表单字段的值,适合于标签中有value属性的标签. 代码: ...

  8. solr 4.3.0 配置

    scheme.xml <?xml version="1.0" encoding="UTF-8" ?> <schema name="t ...

  9. java 面向对象编程 第18章——网络编程

    1.  TCP/IP协议模型 应用层:应用程序: 传输层:将数据套接端口,提供端到端的通信服务: 网络互联层:负责数据包装.寻址和路由,同时还包含网间控制报文协议: 网络接口层:提供TCP/IP协议的 ...

  10. True bar

    真彩bar /***========================================================================= ==== ==== ==== D ...