【题目】

给定两个有序数组arr1和arr2,已知两个数组的长度分别为 m1 和 m2,求两个数组中的第 K 小数。要求时间复杂度O(log(m1 + m2))。

【举例】

例如 arr1 = [1, 2,3],arr2 = [3,4,5,6],K = 4。

则第 K 小数为 3.

例如 arr1 = [0,1,2],arr2 = [3,4,5,7,8], K = 3;

则第 K 小数为 2.

【难度】

解答

这道题和我上次讲的那一道题是非常非常类似的:递归打卡1:在两个长度相等的排序数组中找到上中位数,如果没看过的建议先看下,只是今天的这道题比上次的那道题少难一点,原理一样。

下面我随便讲一下原理吧:采用递归的方法不断缩小 K 的,把求第 K 小元素转化为第 (K-K/2) 小元素....我举个例子吧,比较容易理解。

我们假定 arr1 = [1, 2,3],arr2 = [3,4,5,6],K = 4。

和上一道题类似(注意:这里我们假设K从0算起,也就是有第0小元素,相当于令 K = K - 1),令

mid1 = K/2 = 1。

mid2 = K/2 = 1。

此时 arr2[mid2] > arr2[mid1],那么问题转化为在数组 arr1[mid1+1...m1]和数组 arr2[0...m2] 寻找第(K-md1-1)小的元素。

不过这里需要注意的是,有可能 k/2 的值是大于 m1 或者 m2的,所以如果 k/2 > m1 或者 m2 的话,我们直接令 md1 = m1-1 或者 md2 = m2-1 就行了。

代码如下:

    // 由于中位数会受长度是奇偶数的影响,所以我们可以把问题转化为求
// ((n+m+1)/2+(n+m+2)/2)/2。
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int n = nums1.length;
int m = nums2.length;
// return (findKthNumber(nums1, 0, n-1, nums2,0,m-1,(n+m+1)/2) +
// findKthNumber(nums1, 0, m-1,nums2,0,m-1,(n+m+2)/2)) /2;
return 1;
} public static int findKth(int[] arr1, int[] arr2, int k) {
if(arr1 == null || arr1.length < 1)
return arr2[k-1];
if(arr2 == null || arr2.length < 1)
return arr1[k-1];
// 注意这个函数的参数有7个,上面那个函数的参数只有3个,同名不同函数哈
return findKth(arr1, 0, arr1.length - 1, arr2, 0, arr2.length - 1, k - 1);
} public static int findKth(int[] arr1, int l1, int r1, int[] arr2, int l2, int r2, int k) {
// 递归结束条件
if(l1 > r1)
return arr2[l2 + k];
if(l2 > r2)
return arr1[l1 + k];
if (k == 0)// 注意,k == 0的结束条件与上面两个结束条件不能颠倒。
return Math.min(arr1[l1],arr2[l2]);
int md1 = l1 + k/2 < r1 ? l1 + k/2 : r1;
int md2 = l2 + k/2 < (r2 - l1) ? l2 + k/2 : r2;
if(arr1[md1] < arr2[md2])
return findKth(arr1, md1 + 1, r1, arr2, l2, r2, k - k / 2 - 1);
else if (arr1[md1] > arr2[md2])
return findKth(arr1, l1, r1, arr2, md2 + 1, r2, k - k / 2 - 1);
else
return arr1[md1];//返回arr2[md2]也可以,一样的。
} // 测试
public static void main(String[] args) {
int[] arr1 = {1, 2, 3};
int[] arr2 = {0,4, 5, 6, 7, 8};
System.out.println(findKth(arr1, arr2, 2));
}

可以用迭代吗?当然可以,不过留给你自己。

下次我还会再出一道与这两道类似的题,不过,难度递增。总共有三道这种题,一定要自己手动写代码,一定要自己手动写代码,一定要自己手动写代码。

【递归打卡2】求两个有序数组的第K小数的更多相关文章

  1. 求两个有序数组的中位数或者第k小元素

    问题:两个已经排好序的数组,找出两个数组合并后的中位数(如果两个数组的元素数目是偶数,返回上中位数). 设两个数组分别是vec1和vec2,元素数目分别是n1.n2. 算法1:最简单的办法就是把两个数 ...

  2. 求两个有序数组的中位数(4. Median of Two Sorted Arrays)

    先吐槽一下,我好气啊,想了很久硬是没有做出来,题目要求的时间复杂度为O(log(m+n)),我猜到了要用二分法,但是没有想到点子上去.然后上网搜了一下答案,感觉好有罪恶感. 题目原型 正确的思路是:把 ...

  3. (算法)两个有序数组的第k大的数

    题目: 有两个数组A和B,假设A和B已经有序(从大到小),求A和B数组中所有数的第K大. 思路: 1.如果k为2的次幂,且A,B 的大小都大于k,那么 考虑A的前k/2个数和B的前k/2个数, 如果A ...

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

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

  5. [LeetCode]Median of Two Sorted Arrays 二分查找两个有序数组的第k数(中位数)

    二分.情况讨论 因为数组有序,所以能够考虑用二分.通过二分剔除掉肯定不是第k位数的区间.如果数组A和B当前处理的下标各自是mid1和mid2.则 1.假设A[mid1]<B[mid2], ①.若 ...

  6. 算法-求两个有序数组两两相加的值最小的K个数

    我的思路是: 用队列,  从(0,0)開始入队,每次出队的时候,选(1,0) (0,1) 之间最小的入队,假设是相等的都入队,假设入过队的就不入了,把出队的k个不同的输出来就可以 我測试了几组数据都是 ...

  7. Median of Two Sorted 求两个有序数组的中位数

    中位数是把一个数的集合划分为两部分,每部分包含的数字个数相同,并且一个集合中的元素均大于另一个集合中的元素. 因此,我们考虑在一个任意的位置,将数组A划分成两部分.i表示划分数组A的位置,如果数组A包 ...

  8. 【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 ...

  9. leetcode题目4.寻找两个有序数组的中位数(困难)

    题目描述: 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)). 你可以假设 nums1 和  ...

随机推荐

  1. web页面跳转的几种方式

    可用客户端触发或服务端触发的方式来实现页面跳转. 客户端触发 方式一:使用Javascript 利用window.location对象的href属性.assign()方法或replace()方法来实现 ...

  2. javascript读取xml文件

    什么是 XML? XML 指可扩展标记语言(EXtensible Markup Language) XML 是一种标记语言,很类似 HTML XML 的设计宗旨是传输数据,而非显示数据 XML 标签没 ...

  3. 各浏览器对使用 document.id 和 document.name 获取对象的支持存在差异

    标准参考 无. 问题描述 各浏览器使用 document.id 和 document.name 方法获取对象引用的支持存在差异. 造成的影响 某些浏览器中通过 document.id 和 docume ...

  4. Yii cookie操作

    设置cookie: $cookie = new CHttpCookie('mycookie','this is my cookie'); $cookie->expire = time()+60* ...

  5. hadoop笔记之Hive入门(Hive的体系结构)

    Hive入门(二) Hive入门(二) Hive的体系结构 ○ Hive的元数据 Hive将元数据存储在数据库中(metastore),支持mysql.derby.oracle等数据库,Hive默认是 ...

  6. 你不知道的 页面编码,浏览器选择编码,get,post各种乱码由来

    原文:你不知道的 页面编码,浏览器选择编码,get,post各种乱码由来 asp.net页面编码和浏览器的选择编码 每个asp.net的朋友都知道,在新版本的visual studio,在没有任何设置 ...

  7. Razor视图

    @{ string name="jerry";} <div> @name </div>     //显示jerry @{ string js="& ...

  8. C#基础知识之类和结构体

    虽然项目中一直在使用类.结构体等类型,仔细琢磨,还真无法系统的说出个所以然.记录一下类.结构体.类和结构体区别 一.类 对于类,大家都特别熟悉.简单的介绍一下类的结构,然后记录一下Class需要注意的 ...

  9. Python P图

    Python PIL PIL (Python Image Library) 库是Python 语言的一个第三方库,PIL库支持图像存储.显示和处理,能够处理几乎所有格式的图片. 一.PIL库简介 1. ...

  10. OO学期总结

    一.测试与正确性论证差异对比 测试,顾名思义,就是用一些有意义或无意义的输入去检测程序的正确性或鲁棒性,因其直观明了所以在写简单的程序时我们能迅速找出bug并加以解决.并且,这种方式是绝对客观的,只要 ...