leetcode-4.寻找两个正序数组的中位数

题目:https://leetcode-cn.com/problems/median-of-two-sorted-arrays/

答案:

1、合并排序数组

 public double findMedianSortedArrays(int[] nums1, int[] nums2) {

 int[] nums3= new int[nums1.length+nums2.length];

           int i=0,j=0,k=0;

           while (i<nums1.length && j<nums2.length){

               if(nums1[i]<nums2[j]){

                   nums3[k++]=nums1[i++];

               }else{

                   nums3[k++]=nums2[j++];

               }

           }

           while (i<nums1.length){

               nums3[k++] = nums1[i++];

           }

           while (j<nums2.length){

               nums3[k++] = nums2[j++];

           }

           if(nums3.length%2==0){

               return ((double) nums3[nums3.length/2-1]+(double) nums3[nums3.length/2])/2;

           }else{

               return nums3[nums3.length/2];

           }

    }

时间复杂度为 O(m+n),空间复杂度O(m+n) 不符合要求

2.这里得到了整个有序数组,实际上是不需要知道所有的,只需要知道中位数就行了

如果 m+n 是偶数 ,就得到 (m+n)/2 个数 和(m+n)/2+1 个数 ,也就是 坐标为(m+n)/2 -1 和 (m+n)/2

如果 m+n 是奇数,就得到 (m+n+1)/2 个数,也就是坐标为 (m+n+1)/2-1就行了

  public double findMedianSortedArrays(int[] nums1, int[] nums2) {

  int m = nums1.length;

          int n = nums2.length;

          int length = m+n;

          int left = -1, right = -1;

          int start1 = 0, start2 = 0;

          for(int i=0;i<=length/2;i++){

              left = right;

              if(start1<m && (start2>=n || nums1[start1]<nums2[start2])){

                  right = nums1[start1++];

              }else{

                  right = nums2[start2++];

              }

          }

          if((length&1) == 0) return (left+right)/2.0;

          return right;

    }

题目时间复杂度度 还是O(m+n),控件复杂度为O(1)

3、解法2的进阶版,找第k小数,二分查找思想变种

  public double findMedianSortedArrays(int[] nums1, int[] nums2) {

  int length1= nums1.length;

         int length2 =nums2.length;

         int left = (length1+length2+1)/2;

         int right = (length1+length2+2)/2;

//如果 length1+length2 为奇数,则 left 和 right 相等的,偶数才不相等

         return (getK(nums1,0,length1-1,nums2,0,length2-1,left)+

                 getK(nums1,0,length1-1,nums2,0,length2-1,right))/2.0;

    }

    public int getK(int[] nums1,int start1,int end1,int[] nums2,int start2,int end2,int k){

        int len1 = end1-start1+1;

        int len2 = end2-start2+1;

        if(len1>len2) return getK(nums2,start2,end2,nums1,start1,end1,k);

        if(len1==0) return nums2[start2+k-1];

        if(k==1) return Math.min(nums1[start1],nums2[start2]);

        int index1 = start1 + Math.min(len1,k/2)-1;

        int index2 = start2 + Math.min(len2,k/2)-1;

        if(nums1[index1]>nums2[index2]){

            return getK(nums1,start1,end1,nums2,index2+1,end2,k-(index2-start2+1));

        }else{

            return getK(nums1,index1+1,end1,nums2,start2,end2,k-(index1-start1+1));

        }

    }

时间复杂度 O(log(m+n)),控件复杂度为)O(1)

4.二分查找:

  public double findMedianSortedArrays(int[] nums1, int[] nums2) {

  int m = nums1.length;

        int n = nums2.length;

        if (m > n) {

            return findMedianSortedArrays(nums2,nums1);

        }

        int iMin = 0, iMax = m;

        while (iMin <= iMax) {

            int i = (iMin + iMax) / 2;

            int j = (m + n + 1) / 2 - i;

            if (j != 0 && i != m && nums2[j-1] > nums1[i]){ // i 需要增大

                iMin = i + 1;

            }

            else if (i != 0 && j != n && nums1[i-1] > nums2[j]) { // i 需要减小

                iMax = i - 1;

            }

            else { // 达到要求,并且将边界条件列出来单独考虑

                int maxLeft = 0;

                if (i == 0) { maxLeft = nums2[j-1]; }

                else if (j == 0) { maxLeft = nums1[i-1]; }

                else { maxLeft = Math.max(nums1[i-1], nums2[j-1]); }

                if ( (m + n) % 2 == 1 ) { return maxLeft; } // 奇数的话不需要考虑右半部分

                int minRight = 0;

                if (i == m) { minRight = nums2[j]; }

                else if (j == n) { minRight = nums1[i]; }

                else { minRight = Math.min(nums2[j], nums1[i]); }

                return (maxLeft + minRight) / 2.0; //如果是偶数的话返回结果

            }

        }

        return 0.0;

    }

以时间复杂度是 O(log(min(m,n)),空间复杂度 O(1)

猜你喜欢

转载自blog.csdn.net/wuqiqi1992/article/details/108355775