[Leetcode]4. Median of Two Sorted Arrays

技术文章 4个月前 完美者
1,736 0

标签:mat   median   math   ++   log   二分查找   main   描述   sys   

题目描述

Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays.

Follow up: The overall run time complexity should be O(log (m+n)).

  • Example 1:
Input: nums1 = [1,3], nums2 = [2]
Output: 2.00000
Explanation: merged array = [1,2,3] and median is 2.
  • Example 2:
Input: nums1 = [1,2], nums2 = [3,4]
Output: 2.50000
Explanation: merged array = [1,2,3,4] and median is (2 + 3) / 2 = 2.5.
  • Example 3:
Input: nums1 = [0,0], nums2 = [0,0]
Output: 0.00000
  • Example 4:
Input: nums1 = [], nums2 = [1]
Output: 1.00000
  • Example 5:
Input: nums1 = [2], nums2 = []
Output: 2.00000

给定两个正序数组,求中位数。

第一种解法

class Solution {

  public double findMedianSortedArrays(int[] nums1, int[] nums2) {
    int len1 = nums1.length;
    int len2 = nums2.length;
    int len3 = len1 + len2;
    int[] nums3 = new int[len3];
    int cur1 = 0;
    int cur2 = 0;
    int cur3 = 0;
    while (cur1 < len1 && cur2 < len2) {
      if (nums1[cur1] < nums2[cur2]) {
        nums3[cur3++] = nums1[cur1++];
      } else {
        nums3[cur3++] = nums2[cur2++];
      }
    }
    while (cur1 < len1) {
      nums3[cur3++] = nums1[cur1++];
    }
    while (cur2 < len2) {
      nums3[cur3++] = nums2[cur2++];
    }
    return (nums3[(len3 - 1) / 2] + nums3[len3 / 2]) / 2.0;
  }

  public static void main(String[] args) {
    int[] nums1 = {1};
    int[] nums2 = {2};
    System.out.println(new Solution().findMedianSortedArrays(nums1, nums2));
  }
}

将两个有序数组合并成一个有序数组,时间复杂度O(m+n),空间复杂度O(m+n)。

第二种解法

class Solution2 {

  public double findMedianSortedArrays(int[] nums1, int[] nums2) {
    int len3 = nums1.length + nums2.length;
    int k1 = findKthSmallest(nums1, nums2, (len3 - 1) / 2);
    int k2 = findKthSmallest(nums1, nums2, (len3) / 2);
    return (k1 + k2) / 2.0;
  }

  /**
   * 查找两个数组中第K小元素
   */
  private int findKthSmallest(int[] nums1, int[] nums2, int k) {
    int len1 = nums1.length;
    int len2 = nums2.length;
    int cur1 = 0;
    int cur2 = 0;
    int cur3 = 0;
    while (cur1 < len1 && cur2 < len2) {
      if (nums1[cur1] < nums2[cur2]) {
        if (cur3 == k) {
          return nums1[cur1];
        }
        cur1++;
        cur3++;
      } else {
        if (cur3 == k) {
          return nums2[cur2];
        }
        cur2++;
        cur3++;
      }
    }
    while (cur1 < len1) {
      if (cur3 == k) {
        return nums1[cur1];
      }
      cur1++;
      cur3++;
    }
    while (cur2 < len2) {
      if (cur3 == k) {
        return nums2[cur2];
      }
      cur2++;
      cur3++;
    }
    return -1;
  }

  public static void main(String[] args) {
    int[] nums1 = {1, 3};
    int[] nums2 = {2};
    System.out.println(new Solution2().findMedianSortedArrays(nums1, nums2));
  }
}

不合并数组,找到中位数所在位置,时间复杂度O(m+n),空间复杂度O(1)。

第三种解法

class Solution3 {

  public double findMedianSortedArrays(int[] nums1, int[] nums2) {
    int len3 = nums1.length + nums2.length;
    int k1 = findKthSmallest(nums1, 0, nums2, 0, (len3 + 1) / 2);
    int k2 = findKthSmallest(nums1, 0, nums2, 0, (len3 + 2) / 2);
    return (k1 + k2) / 2.0;
  }

  /**
   * 查找两个数组中第K小元素,K范围为[1,,len]
   */
  private int findKthSmallest(int[] nums1, int nums1Left, int[] nums2, int nums2Left, int k) {
    int len1 = nums1.length;
    int len2 = nums2.length;
    //第一个数组查找完,直接查找第二个数组
    if (nums1Left >= len1) {
      return nums2[nums2Left + k - 1];
    }
    //第二个数组查找完,直接查找第一个数组
    if (nums2Left >= len2) {
      return nums1[nums1Left + k - 1];
    }
    if (k == 1) {
      return Math.min(nums1[nums1Left], nums2[nums2Left]);
    }
    //中位数向下取整
    int middleVal1 =
        (nums1Left + k / 2 - 1 < len1) ? nums1[nums1Left + k / 2 - 1] : Integer.MAX_VALUE;
    int middleVal2 =
        (nums2Left + k / 2 - 1 < len2) ? nums2[nums2Left + k / 2 - 1] : Integer.MAX_VALUE;
    if (middleVal1 < middleVal2) {
      return findKthSmallest(nums1, nums1Left + k / 2, nums2, nums2Left, k - k / 2);
    } else {
      return findKthSmallest(nums1, nums1Left, nums2, nums2Left + k / 2, k - k / 2);
    }
  }

  public static void main(String[] args) {
    int[] nums1 = {1, 2};
    int[] nums2 = {3, 4};
    System.out.println(new Solution3().findMedianSortedArrays(nums1, nums2));
  }
}

使用二分查找,将问题转换成求两个数组中第K小元素的问题。时间复杂度O(log(m+n))。

[Leetcode]4. Median of Two Sorted Arrays

标签:mat   median   math   ++   log   二分查找   main   描述   sys   

原文地址:https://www.cnblogs.com/strongmore/p/14294839.html

版权声明:完美者 发表于 2021-01-19 12:12:17。
转载请注明:[Leetcode]4. Median of Two Sorted Arrays | 完美导航

暂无评论

暂无评论...