Leetcode Median of Two Sorted Arrays (java)

解法一:

import java.util.Arrays;
class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        //存储合并后的数组
        int[] nums3 = new int[nums1.length + nums2.length];
        for (int i = 0; i < nums3.length; i++) {
             if(i < nums1.length){
                 nums3[i] = nums1[i];
             }
             else {
                 nums3[i] = nums2[i-nums1.length];
             }
        }
        //进行升序排序
        Arrays.sort(nums3);
        //寻找median
        double median;
        if(nums3.length % 2 == 1){
             median = nums3[(nums3.length/2) ];
        }
        else{
             median = (nums3[((nums3.length/2))]+nums3[(nums3.length/2)-1])/2.0;
        }
        return median;
    }
}

该解法思路是把两个数组合并,进行升序排序,取中间值

 

解法二:

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
       int n = nums1.length;
       int m = nums2.length;
       //让nums1始终最短
       //若num2比nums1长会出现数组越界问题
       if(n > m){
           return findMedianSortedArrays(nums2,nums1);
       }
       int l1;//nums1左部分最右的元素
       int r1;//nums1右部分最左的元素
       int c1;//nums1分割位置
       int l2;//nums2左部分最右的元素
       int r2;//nums2右部分最左的元素
       int c2;//nums2分割部分
        //让数组恒为奇数
       int start = 0;
       int end = 2 * n + 1 - 1;
       //开始不断分割nums1
       while (start <= end){
           //c1 c2保证了是前m+n个数 数组总长为2(m+n)
           c1 = (start + end) / 2;
           c2 = m + n - c1;

           l1 = c1 == 0 ? Integer.MIN_VALUE : nums1[(c1 - 1 ) / 2];
           r1 = c1 >= 2*n ? Integer.MAX_VALUE : nums1[(c1) / 2];

           l2 = c2 == 0 ? Integer.MIN_VALUE : nums2[(c2 - 1) / 2];
           r2 = c2 >= 2*m ? Integer.MAX_VALUE : nums2[(c2) / 2];

           //l1减少 r2增大
           if(l1 > r2){
               end = c1 - 1;
           }
           //r1增大 l2减少
           else if(l2 > r1){
               start = c1 + 1;
           }
           else {
               double median = ( Math.max(l1,l2) + Math.min(r1,r2) ) / 2.0;
               return median;
           }
       }
       return 0.0;
    }
}

 该解法思路是:

  用两个分割位置把两个数组各自分成两部分,两个数组即是四部分,为l1,r1,l2,r2

  由于取的是中值,即是取第m+n个(这个做法是因为把数组长度都假设成了2*n + 1个来让数组为奇数个)

  分割的位置先是第一个数组的一半,第二个数组是 m+n - 第一个数组的位置,为了保证两个数组的左部分加起来个数是m+n来取到第m+n个数

  并且要保证两个左半部分要恒小于两个右半部分,即是l1<r1&&l1<r2 和 l2<r2&&l2<r1 因为已经是有序数组,所以有一半可以忽略,即是 l1<r2 && l2<r1

  若不满足上述条件,就把分割位置进行移动,此时正确的位置肯定在其中一边,把另一边舍去后继续二分直到符合上述条件

  当满足上述条件,l1和l2最大的,r1和r2最小的,它们的和除以2就可以得出答案

关于边界问题:

  只要保证nums1<=nums2即可,因为若出现nums1>nums2的时候,会出现nums2的分割位置出现数组越界的情况

 

github地址:https://github.com/CyanChan/leetcode

  

posted @ 2018-03-05 15:25  CyanChan  阅读(158)  评论(0编辑  收藏  举报