zoukankan      html  css  js  c++  java
  • OJ练习43——T4 Median of Two Sorted Arrays

    两个有序数列A B,长度分别为m,n,求它们的中位数,要求时间复杂度是O(log(m+n)).

    解读:即求两数列按序合并后的中位数。

    【思路】

    1.mine:两个指针i,j分别指向两列的头,当a[i]<b[j]时,i++,反之,j++。当(i+j)==(m+n-2)/2时,即返回当前值。时间复杂度是O(m+n)。

    2.others:求第K小的数,核心是当a[k/2-1]<b[k/2-1]时,a[0]——a[k/2-1]必定都小于第K小的数。用递归每次排除掉一半,直到a[k/2-1]=b[k/2-1]时返回该值。

    【my code】

    尝试用思路1来写代码,当循环结束,要考虑的情况简直太太太多,分不清楚!

    因为当m+n是偶数,无法判断前后两个连续大小的值,

    当两列有很多相同的值时也无法找到。

    放弃。(理论来说是可行的,暂时没想到好方法解决,待我再长长翅膀)

    ===更新===

    从后向前呢?两个序列从后向前“删除”比第K小的数大的数,计数直到个数达到 length/2,代码很简单,还没在线上通过。

    【other code】

    double findKth(int a[], int m, int b[], int n, int k)
    {
        //always assume that m is equal or smaller than n
        if (m > n)
            return findKth(b, n, a, m, k);
        if (m == 0)
            return b[k - 1];
        if (k == 1)
            return min(a[0], b[0]);
        //divide k into two parts
        int pa = min(k / 2, m), pb = k - pa;
        if (a[pa - 1] < b[pb - 1])
            return findKth(a + pa, m - pa, b, n, k - pa);
        else if (a[pa - 1] > b[pb - 1])
            return findKth(a, m, b + pb, n - pb, k - pb);
        else
            return a[pa - 1];
    }
    
    class Solution
    {
    public:
        double findMedianSortedArrays(int A[], int m, int B[], int n)
        {
            int total = m + n;
            if (total & 0x1)
                return findKth(A, m, B, n, total / 2 + 1);
            else
                return (findKth(A, m, B, n, total / 2)
                        + findKth(A, m, B, n, total / 2 + 1)) / 2;
        }
    };

    【分析】

    题目改成了vector,每次删掉一半从后半段找实现起来较为困难,于是改掉接口,用迭代器指向。修改如下:

    typedef vector<int>::const_iterator iter;
    double findKth(vector<int>& nums1,vector<int>& nums2,iter st1,iter end1,iter st2, iter end2,int k)
    {  
        //always assume that m is equal or smaller than n 
        int m=end1-st1;
        int n=end2-st2;
        if (m > n)  
            return findKth(nums2, nums1, st2,end2,st1,end1, k);  
        if (m == 0)  
            return *(st2+k-1);  
        if (k == 1)  
            return min(*st1, *st2);  
        //divide k into two parts  
        int pa = min(k / 2, m), pb = k - pa;  
        if (*(st1+pa-1) < *(st2+pb-1))  
            return findKth(nums1,nums2, st1+pa,end1,st2,end2,k - pa);  
        else if (*(st1+pa-1) > *(st2+pb-1))  
            return findKth(nums1,nums2, st1,end1,st2+pb,end2,k - pb);  
        else  
            return *(st1+pa-1);  
    }  
    class Solution {
    public:
        double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
            int m=nums1.size();
            int n=nums2.size();
            int total=m+n;
            if(total%2==0){
                return 
                (findKth(nums1,nums2,nums1.begin(),nums1.end(),nums2.begin(),nums2.end(),total/2)+
                findKth(nums1,nums2,nums1.begin(),nums1.end(),nums2.begin(),nums2.end(),total/2+1))/2;
            }
            if(total%2!=0){
                return findKth(nums1,nums2,nums1.begin(),nums1.end(),nums2.begin(),nums2.end(),total/2+1);
            }
        }
    };

    【结果】

    61ms,排名靠后。一定还有更简单的。可是网上现在看到的基本都是这个方法了……以后再战。

    原来是一道HARD!!!原来是一道HARD!!!

  • 相关阅读:
    Spring Tool Suite 配置和使用
    自动提示在线/离线状态
    Excel数据导入数据库的SQL快速生成
    MySQL查询和删除重复数据
    内存不足时,调用ajax报的错
    订单支付成功后存储过程
    下订单存储过程
    课程表,订单表(统计报名人数),评论表(统计评论的人数),点赞表(点赞人数)
    更改浏览器的滚动条样式
    自定义文本选中样式
  • 原文地址:https://www.cnblogs.com/ketchups-notes/p/4481175.html
Copyright © 2011-2022 走看看