• LeetCode4 Median of Two Sorted Arrays


    题目:

    There are two sorted arrays nums1 and nums2 of size m and n respectively.

    Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).   (Hard)

    Example 1:

    nums1 = [1, 3]
    nums2 = [2]
    
    The median is 2.0

    Example 2:

    nums1 = [1, 2]
    nums2 = [3, 4]
    
    The median is (2 + 3)/2 = 2.5


    分析:
    利用寻找第K个元素的辅助函数。
    二分搜索的思想,每次尽量去掉数组中的一部分元素(一半左右);
    一次取K个元素出来,nums1中取 K/2个(不够就全都取出), nums2中取 K - K/2(或nums1.size()),
    判断取出的两个数组元素中的末位谁大谁小;
    如果nums1[p1] < nums2[p2],说明nums1取少了,nums2取多了,第K个元素应该在nums1的后半部分或nums2的前半部分;
    如果nums1[p1] > nums2[p2], 说明nums2取少了,nums1取多了,第K个元素应该在nums2的后半部分或nums1的前半部分;
    递归求解即可 。边界条件是nums1或nums2为空或K为1;

    注:题目思路不是很难想到,但是处理细节有很多容易错的地方。
    1.首先应确定Kth是第K个元素,对应下标应该为K-1
    2.数组下标,取1/2位置时对应的哪个位置等等要注意,可以采用走样例的方式保证不出错。
    3.采用了两种实现方法,一种是拷贝vector,要传参的时候注意左闭右开;
               另一种是不拷贝vector,多传两个起始位置start,注意每次取元素操作时不能忘记start
    第二个效率稍高,但编码中可能出错的地方也多一点。

    代码1:
     1 class Solution {
     2 private:
     3     double findKth(vector<int>& nums1, vector<int>& nums2, int K) { //第K个,对应下标K-1
     4         if (nums1.size() > nums2.size()) {
     5             return findKth(nums2,nums1,K);
     6         }
     7         if (nums1.size() == 0) {
     8             return nums2[K-1];
     9         }
    10         if (nums2.size() == 0) {
    11             return nums1[K-1];
    12         }
    13         if (K == 1) {
    14             return min(nums1[0], nums2[0]);
    15         }
    16         int s = nums1.size();
    17         int p1 = min( K / 2, s);
    18         int p2 = K - p1;
    19         if (nums1[p1 - 1] < nums2[p2 - 1]) { //说明nums1取少了,kth在nums1后半段或nums2前半段
    20             vector<int> n1(nums1.begin() + p1, nums1.end());
    21             vector<int> n2(nums2.begin(), nums2.begin() + p2);
    22             return findKth(n1, n2, K - p1);
    23         }
    24         else {
    25             vector<int> n3(nums1.begin(), nums1.begin() + p1);
    26             vector<int> n4(nums2.begin() + p2, nums2.end());
    27             return findKth(n3, n4, K - p2);
    28         }
    29      }
    30 public:
    31     double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
    32         int s1 = nums1.size(), s2 = nums2.size();
    33         int mid = (s1 + s2) / 2;
    34         if ( (s1 + s2) % 2 == 0 ) {
    35             return (findKth(nums1, nums2, mid) + findKth(nums1, nums2, mid + 1)) / 2.0; 
    36         } 
    37         else {
    38             return findKth(nums1, nums2, mid + 1);
    39         }
    40     }
    41 };

    代码2:

     1 class Solution {
     2 private:
     3     double findKth(vector<int>& nums1, vector<int>& nums2, int K ,int start1, int start2) { //第K个,对应下标K-1
     4         if (nums1.size() - start1 > nums2.size() - start2) {
     5             return findKth(nums2,nums1,K,start2,start1);
     6         }
     7         if (nums1.size() - start1 == 0) {
     8             return nums2[start2 + K - 1];
     9         }
    10         if (nums2.size() - start2 == 0) {
    11             return nums1[start1 + K - 1];
    12         }
    13         if (K == 1) {
    14             return min(nums1[start1], nums2[start2]);
    15         }
    16         int s = nums1.size() - start1;
    17         int p1 =  min( K / 2, s);
    18         int p2 =  K - p1;
    19         if (nums1[start1 + p1 - 1] < nums2[start2 + p2 - 1]) { //说明nums1取少了,kth在nums1后半段或nums2前半段
    20             return findKth(nums1, nums2, K - p1, start1 + p1,start2);
    21         }
    22         else {
    23             return findKth(nums1, nums2, K - p2, start1, start2 + p2);
    24         }
    25      }
    26 public:
    27     double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
    28         int s1 = nums1.size(), s2 = nums2.size();
    29         int mid = (s1 + s2) / 2;
    30         if ( (s1 + s2) % 2 == 0 ) {
    31             return (findKth(nums1, nums2, mid,0,0) + findKth(nums1, nums2, mid + 1,0,0)) / 2.0; 
    32         } 
    33         else {
    34             return findKth(nums1, nums2, mid + 1,0,0);
    35         }
    36     }
    37 };

    其他与二分搜索相关的问题可以参考:

    http://www.cnblogs.com/wangxiaobao/p/4915853.html

     






  • 相关阅读:
    第十一周课程总结
    第十周课程总结
    第九周课程总结&实验报告(七)
    第八周课程总结&实验报告六
    第七周
    第六周
    课程总结
    第十四周课程总结&实验报告
    第十三周总结
    第十二周总结
  • 原文地址:https://www.cnblogs.com/wangxiaobao/p/5727003.html
Copyright © 2020-2023  润新知