寻找两个有序数组的中位数(LeetCode 4)

❤ 作者主页:李奕赫揍小邰的博客
❀ 个人介绍:大家好,我是李奕赫!( ̄▽ ̄)~*
记得点赞、收藏、评论⭐️⭐️⭐️
认真学习!!!

文章目录

  • 解法一:暴力法
  • 解法二:指针法
  • 解法三:二分查找法

给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。

算法的时间复杂度应该为 O(log (m+n)) 。
寻找两个有序数组的中位数(LeetCode 4)_第1张图片

 

解法一:暴力法

  直接新建一个数组,将两个数组合并到一起,然后排序后取中位值。

public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int length1=nums1.length;
        int length2=nums2.length;
        int nums3[]=new int[length1+length2];
        for(int i=0;i<length1;i++)
            nums3[i]=nums1[i];
        for(int j=0;j<length2;j++)
            nums3[length1+j]=nums2[j];
        Arrays.sort(nums3);
        int length3=nums3.length;
        double temp;
        if(length3%2==0)
            temp=(nums3[length3/2]+nums3[length3/2-1])/2.0;
        else
            temp=nums3[length3/2];
        return temp;
    }

 

解法二:指针法

  不需要合并两个有序数组,只要找到中位数的位置即可。由于两个数组的长度已知,因此中位数对应的两个数组的下标之和也是已知的。维护两个指针,初始时分别指向两个数组的下标 000 的位置,每次将指向较小值的指针后移一位(如果一个指针已经到达数组末尾,则只需要移动另一个数组的指针),直到到达中位数的位置。

代码就不再展示。
 

解法三:二分查找法

  根据中位数的定义,当 m+n是奇数时,中位数是两个有序数组中的第 (m+n)/2 个元素,当 m+n是偶数时,中位数是两个有序数组中的第 (m+n)/2个元素和第 (m+n)/2+1个元素的平均值。因此,这道题可以转化成寻找两个有序数组中的第 k小的数,其中 k 为 (m+n)/2或 (m+n)/2+1。

public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int length1 = nums1.length, length2 = nums2.length;
        int totalLength = length1 + length2;
        if (totalLength % 2 == 1) {
            int midIndex = totalLength / 2;
            double median = getKthElement(nums1, nums2, midIndex + 1);
            return median;
        } else {
            int midIndex1 = totalLength / 2 - 1, midIndex2 = totalLength / 2;
            double median = (getKthElement(nums1, nums2, midIndex1 + 1) + getKthElement(nums1, nums2, midIndex2 + 1)) / 2.0;
            return median;
        }
    }
    public int getKthElement(int[] nums1, int[] nums2, int k) {
        int length1 = nums1.length, length2 = nums2.length;
        int index1 = 0, index2 = 0;
        int kthElement = 0;

        while (true) {
            if (index1 == length1) {
                return nums2[index2 + k - 1];
            }
            if (index2 == length2) {
                return nums1[index1 + k - 1];
            }
            if (k == 1) {
                return Math.min(nums1[index1], nums2[index2]);
            }
            
            // 正常情况
            int half = k / 2;
            int newIndex1 = Math.min(index1 + half, length1) - 1;
            int newIndex2 = Math.min(index2 + half, length2) - 1;
            int pivot1 = nums1[newIndex1], pivot2 = nums2[newIndex2];
            if (pivot1 <= pivot2) {
                k -= (newIndex1 - index1 + 1);
                index1 = newIndex1 + 1;
            } else {
                k -= (newIndex2 - index2 + 1);
                index2 = newIndex2 + 1;
            }
        }
    }


 


你可能感兴趣的:(LeetCode,leetcode,算法,数据结构)