美文网首页
LeetCode Problem No.4

LeetCode Problem No.4

作者: kino831143 | 来源:发表于2018-12-25 23:28 被阅读0次

    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)).
    You may assume nums1 and nums2 cannot be both empty.

    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
    

    Solution 1:

    int len1 = nums1.size();
    int len2 = nums2.size();
    vector<int> list;
    //每次都从nums1和nums2中找小的push_back进去,
    //直到vector的size 为 (len1+len2)/2;
    if((len1+len2)%2==0)
    {
        return list[ (len1+len2)/2];
    }
    else
    {
        return (list[ (len1+len2)/2]+ list[ (len1+len2)/2-1])/2.0;
    }
    //缺点:申请了新的内存,时间是(m+n)/2 不是long(m+n)
    //但是时间效果比使用二分查找速度快
    

    Solution 2:

    //开辟新的空间,寻找中位数,实际上和上面思路基本相同
    //缺点:时间复杂度不是log(m+n)
    class Solution {
    public:
        double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
            int num1 = nums1.size();
            int num2 = nums2.size();
            if(num1 == 0 && num2 == 0)
                return 0.0;
            int total = num1 + num2;
            int mid = total / 2;
            int flag = total % 2;
            int left1 = 0;
            int left2 = 0;
            int count = 0;
            if(flag == 0)
            {
                int res = 0;
                while(count < mid)
                {
                    if(left1<num1 && left2<num2)
                    {
                        if(nums1[left1]<nums2[left2])
                        {
                            res = nums1[left1];
                            left1++;
                            count++;
                        }
                        else
                        {
                            res = nums2[left2];
                            left2++;
                            count++;
                        }
                    }
                    else if(left1<num1 && left2==num2)
                    {
                        res = nums1[left1];
                        left1++;
                        count++;
                    }
                    else if(left1==num1 && left2<num2)
                    {
                        res = nums2[left2];
                        left2++;
                        count++;
                    }
                }
                
                int res2 = 0;
                if(left1<num1 && left2<num2)
                {
                    if(nums1[left1]<nums2[left2])
                    {
                        res2 = nums1[left1];
                    }
                    else if(nums1[left1]>nums2[left2])
                    {
                        res2 = nums2[left2];
                    }
                    else
                    {
                        res2 = nums1[left1];
                    }       
                }
                else if(left1<num1 && left2==num2)
                {
                    res2 = nums1[left1];
                }
                else if(left1==num1 && left2<num2)
                {
                    res2 = nums2[left2];
                }
                double result = (res2 + res)/2.0;
                return result;
                
            }
            else
            {
                int median = mid;
                int res = 0;
                while(count <= mid)
                {
                    if(left1<num1 && left2<num2)
                    {
                        if(nums1[left1]<nums2[left2])
                        {
                            res = nums1[left1];
                            left1++;
                            count++;
                        }
                        else
                        {
                            res = nums2[left2];
                            left2++;
                            count++;
                        }
                    }
                    else if(left1<num1 && left2==num2)
                    {
                        res = nums1[left1];
                        left1++;
                        count++;
                    }
                    else if(left1==num1 && left2<num2)
                    {
                        res = nums2[left2];
                        left2++;
                        count++;
                    }
                }
                double result = res * 1.0;
                return result;
            }
            return 0;
        }
    };
    

    Solution 3:

    //题目中明确要求时间复杂度为log(m+n)
    //搜索时应该使用二分方法进行搜索
    //常见的二分法是针对一个数组设置left和right标志,进算mid位与目标值大小关系来确定left和right的新值
    //数组nums1的长度为m,nums2的长度为n
    //假设存在i和j,i在[0,m-1]范围内,j在[0,n-1]范围内
    //能使得nums1[0]~nums1[i-1]和nums2[0]~num2[j-1]恰好在中位左侧
    //nums1[i]~nums1[m-1]和nums2[j]~nums2[j-1]恰好在中位右侧
    //那么 i+j = m - i + j-i 或 i+j = m-i+n-j+1
    //可以得到 i+j = (m+n+1)/2
    //如果 i 属于[0,m-1] 那么 j = (m+n+1)/2 - i
    //如果m>n 则 j可能是负数,因此这种情况下,我们交换nums1和nums2即可
    //则问题就变成了找到合适的i,j使得nums2[j-1]<=nums1[i]并且nums1[i-1]<=nums2[j],由于可以由i计算j那么在[0,m-1]中寻找i即可,可以使用二分法查找
    class Solution {
    public:
        double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
            int m = nums1.size();
            int n = nums2.size();
            if(m>n)
            {
                return findMedianSortedArrays(nums2,nums1);
            }
            
            int left = 0;
            int right = m;
            int mid = (m+n+1)/2;
            while(left<=right)
            {
                int i = (left+right)/2;
                int j = mid - i;
                if(i<right&&nums2[j-1]>nums1[i])
                {
                    left = i+1;
                }
                else if(i>left&&nums1[i-1]>nums2[j])
                {
                    right = i-1;
                }
                else
                {
                    int maxleft = 0;
                    if(i==0)
                    {
                        maxleft=nums2[j-1];
                    }
                    else if(j==0)
                    {
                        maxleft=nums1[i-1];    
                    }
                    else
                    {
                        if(nums2[j-1]>nums1[i-1])
                        {
                            maxleft=nums2[j-1];
                        }
                        else
                        {
                            maxleft=nums1[i-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
                    {
                         if(nums2[j]>nums1[i])
                        {
                            minright=nums1[i];
                        }
                        else
                        {
                            minright=nums2[j];
                        }
                    }
                    return (maxleft+minright)/2.0;
                }
            }
            return 0.0;
        }
    

    相关文章

      网友评论

          本文标题:LeetCode Problem No.4

          本文链接:https://www.haomeiwen.com/subject/wtqclqtx.html