Leetcode 4. Median of Two Sorted Arrays

来源:互联网 发布:ios数据存储方式sqlite 编辑:程序博客网 时间:2024/06/14 18:48

题目描述:

There are two sorted arrays nums1 and nums2 of size m and n respectively.

Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

Example 1:

nums1 = [1, 3]nums2 = [2]The median is 2.0

Example 2:

nums1 = [1, 2]nums2 = [3, 4]The median is (2 + 3)/2 = 2.5

解析:

这道题初一看感觉挺简单,但一看时间复杂度要求O(log(m+n)),就很头疼,因为一般排序方法平均时间复杂度大多是O(nlogn),所以一开始想用排序的思路来做,但总是行不通,后来觉得自己学过的算法中时间复杂度能到O(log(m+n))只有折半查找这样的方法,试着自己想了下,又去看了下往上的题解,终于解决了这道题。下面两种思路都说一下。

(1)、归并排序

因为本身题目中已经给出了num1与num2两个数组,且均已经排好序,所以只要把两个数组合并,再根据元素总数的奇偶性即可求出结果,若总数为奇,返回num[(m+n)/2],若为偶,返回{num[(m+n)/2-1]+num[(m+n)/2]}/2。因为两个数组均已排好序,所以归并时总共遍历一遍即可,时间复杂度为O(m+n)。这种方法实现比较简单,测试也过了,但显然不符合题目要求。

(2)、二分法

采用经典的递归折半查找的方式来解决。将这个问题转化为求第K小的数的问题,奇偶的结果与上文中叙述的类似。我们假定num1为长度较小的数组,通过比较num1的长度m与k/2的关系,将k划分为两部分:1、若m较小,则划分为pa=m与pb=k-m。2、若k/2较小,则划分为pa=k/2与pb=k-(k/2)。

若num1[pa-1]<num2[pb-1],说明num1[pa-1]不可能在合并后的数组的第k-1位上,所以从num1开始到pa-1中的所有元素均可舍弃。

若num1[pa-1]>num2[pb-1],与上同理,将num2处理。

若num1[pa-1]==num2[pb-1],这两个元素就是第k个元素,递归结束。

注意还有以下边界条件,作为递归结束条件:

若m==0,则说明Num1等于0,直接返回num2[k-1]

若k==1,则直接比较num1[0]与num2[0]中的小者返回。

因为每次均将其减少(m+n)/2的规模,所以算法的时间复杂度O(log(m+n)):

原始代码:

public class Solution {    public double findMedianSortedArrays(int[] nums1, int[] nums2) {        int m=nums1.length;        int n=nums2.length;        int total = m + n;        if (total%2==1) {        return findKnum(nums1,0,m,nums2,0,n,total/2+1);        }else{        double temp1=findKnum(nums1,0,m,nums2,0,n,total/2);        double temp2=findKnum(nums1,0,m,nums2,0,n,total/2+1);        return (temp1+temp2)/2;        }    }private double findKnum(int[] A,int astart,int m,int[] B,int bstart,int n,int k){if(m>n)return findKnum(B,bstart,n,A,astart,m,k);if(m==0)return B[k-1];if(k==1)return A[astart]<B[bstart]?A[astart]:B[bstart];int pa=(k/2)<m?(k/2):m;int pb=k-pa;if(A[astart+pa-1]<B[bstart+pb-1]){return findKnum(A,astart+pa,m-pa,B,bstart,n,k-pa);}else if(A[astart+pa-1]>B[bstart+pb-1]){return findKnum(A,astart,m,B,bstart+pb,n-pb,k-pb);}else{return A[pa-1];}}}

总结:

上周刚放假回来,机器学习课和线性代数课都没听完,又要忙比赛和毕设啥的,就写了三道题,真挺惭愧的。不过好在我还有挺长时间,只要能把知识弄懂就行,哪怕掌握的慢点,只要有进步就是好事。

这道题算是我上周做的三道题中最有难度的一道了,主要是缩小时间复杂度这里不太好想,得到的锻炼也是最大的,希望下周能取得更大的进步!


0 0
原创粉丝点击