[LeetCode]习题5

来源:互联网 发布:linux查看端口状态 编辑:程序博客网 时间:2024/06/05 03:27

[LeetCode]习题

先贴本次习题的地址https://leetcode.com/problems/median-of-two-sorted-arrays/description/

这道题比之前做的题要难,因为是对两个已排序数组找中位数的题,难度体现在对时间复杂度上,要求时间复杂度为 O(log (m+n)),也就是不能创建新的数组,也不能使用内外循环的方法,只能对每次取出的数判断是否为中位数且只取一次。
于是我们同时从两个数组的头开始向后,每次把头一个拿出来与另一个数组的比较,如果小的话,该数组索引增加而另一个数组索引不变,直到获得中位数。
难点在于:
一、两个数组的长度之和为单还是双
二、数组有可能为空
三、有可能当一个数组元素取完后还没得到中位数

对于第一个可分两种情况讨论,总长度取余2的结果分两种情况。为偶数时,需要取两个数平均数
对于第二个也分两种情况,第一个为空或者第二个为空。然后对于一个数组求中位数较简单。
对于第三种情况很容易忽略导致一直不知道错在哪(我一开始就是)。超出边界要考虑进去。

下面贴代码

class Solution {    public double findMedianSortedArrays(int[] nums1, int[] nums2) {        if(nums1.length==0){            int l2 = nums2.length;            int mid2 = l2/2;            double middle = 0;            if(l2%2==1){                middle = nums2[mid2];                return middle;            }               else{                middle = (double)(nums2[mid2-1]+nums2[mid2])/2;                return middle;            }           }        if(nums2.length==0){            int l1 = nums1.length;            int mid1 = l1/2;            double middle = 0;            if(l1%2==1){                middle = nums1[mid1];                return middle;            }               else{                middle = (double)(nums1[mid1-1]+nums1[mid1])/2;                return middle;            }           }        int l = nums1.length+nums2.length;        int mid = l/2;        double change = 0;        if(l%2 == 1){            int i = -1;            for(int x =0,y=0;x<nums1.length||y<nums2.length;){                if(x<nums1.length && y<nums2.length && nums1[x]<=nums2[y]){                    change = nums1[x];                    x++;                }                else if(x<nums1.length && y<nums2.length && nums1[x]>nums2[y]){                    change = nums2[y];                    y++;                }                else if(x==nums1.length){                    change = nums2[y];                    y++;                }                else if(y==nums2.length){                    change = nums1[x];                    x++;                }                i++;                if(i == mid)                    break;            }        }else{            int i = -1;            double first = 0;            for(int x =0,y=0;x<nums1.length||y<nums2.length;){                if(x<nums1.length && y<nums2.length && nums1[x]<=nums2[y]){                    change = nums1[x];                    x++;                }                else if(x<nums1.length && y<nums2.length && nums1[x]>nums2[y]){                    change = nums2[y];                    y++;                }                else if(x==nums1.length){                    change = nums2[y];                    y++;                }                else if(y==nums2.length){                    change = nums1[x];                    x++;                }                i++;                if(i == mid-1)                    first = change;                if(i == mid){                    change = (first + change)/2;                    break;                }            }        }       return change;     }}

我的代码直接对第一个数组和第二个数组进行分类讨论,其实可以化简为一种那就是把数组分成长的数组和短的数组,如果长短和我们所设不同,我们就可以交换他们,可以少大概三分之一的代码。我没有尝试,同学们可以试试。