leetcode 4 两个正序数组中位数

普通方法,就算总的数个数,然后通过双指针的方法访问数组中的元素,可以搞出来,但是时间复杂度不是log的,先贴下代码

  1 class Solution {
  2 public:
  3     double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) 
  4     {
  5         int n1 = nums1.size();
  6         int n2 = nums2.size();
  7         int n = nums1.size() + nums2.size();
  8         double res = 0;
  9         if(n%2 == 0) // 整除2
 10         {
 11             int k1 = n/2;
 12             int k2 = n/2+1;
 13             int l = 0;
 14             int i = -1;
 15             int j = -1;
 16             while(l+1 < k1) // 未找到中位数的所在位置
 17             {
 18                 if(i+1<n1 && j+1<n2)
 19                 {
 20                     if(nums1[i+1]<=nums2[j+1]) //较小的为下一个
 21                     {
 22                         i++;
 23                         l++;
 24                     }
 25                     else
 26                     {
 27                         j++;
 28                         l++;
 29                     }    
 30                 }
 31                 else if(i+1 < n1)
 32                 {
 33                     i++;
 34                     l++;
 35                 }
 36                 else if(j+1 < n2)
 37                 {
 38                     j++;
 39                     l++;  
 40                 }
 41             }
 42             //找到位置
 43             for(int t = 0 ; t <= 1 ; t++)
 44             {
 45                 if(i+1<n1 && j+1<n2)
 46                 {
 47                     if(nums1[i+1]<=nums2[j+1]) //较小的为下一个
 48                     {
 49                         res+=nums1[i+1];
 50                         i++;
 51                         l++;
 52                     }
 53                     else
 54                     {
 55                         res+=nums2[j+1];
 56                         j++;
 57                         l++;
 58                     }
 59                 }
 60                 else if(i+1 < n1)
 61                 {
 62                     res+=nums1[i+1];
 63                     i++;
 64                     l++;
 65                 }
 66                 else if(j+1 < n2)
 67                 {
 68                     res+=nums2[j+1];
 69                     j++;
 70                     l++;  
 71                 }
 72             }
 73             return res/2;
 74         }
 75         else
 76         {
 77             if(n == 1)
 78             {
 79                 if(nums1.size())
 80                 return nums1[0];
 81                 else
 82                 return nums2[0];
 83             }
 84             int k = (n+1)/2;
 85             int l = 0;
 86             int i = -1;
 87             int j = -1;
 88             // 未找到中位数的所在位置 
 89             while(l+1 < k) 
 90             {
 91                 if(i+1<n1 && j+1<n2)
 92                 {
 93                     if(nums1[i+1]<=nums2[j+1]) //较小的为下一个
 94                     {
 95                         i++;
 96                         l++;
 97                     }
 98                     else
 99                     {
100                         j++;
101                         l++;
102                     }    
103                 }
104                 else if(i+1 < n1)
105                 {
106                     i++;
107                     l++;
108                 }
109                 else if(j+1 < n2)
110                 {
111                     j++;
112                     l++;  
113                 }
114             }
115             //找到位置
116             if(i+1<n1 && j+1<n2)
117             {
118                 if(nums1[i+1]<=nums2[j+1]) //较小的为下一个
119                 {
120                     res=nums1[i+1];
121                     i++;
122                     l++;
123                 }
124                 else
125                 {
126                     res=nums2[j+1];
127                     j++;
128                     l++;
129                 }
130             }
131             else if(i+1 < n1)
132             {
133                 res=nums1[i+1];
134                 i++;
135                 l++;
136             }
137             else if(j+1 < n2)
138             {
139                 res=nums2[j+1];
140                 j++;
141                 l++;  
142             }
143             return res; 
144         }        
145     }
146 };

第二种方法是神奇的二分查找,对于题目的要求,等同于找等价序列中的第K个元素,或着K和第K加1个元素。所以对于这两个序列,可以比较其索引为K/2-1的元素的相对大小,对于其中较小的值,其最多也只能比k-2个元素大,所以该元素包括该序列中的之前所有元素都可以排除。依照这个思路,可以在每一轮迭代中排除一部分元素,并更新K的值,不断进行迭代。

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) 
    {
        int m = nums1.size();
        int n = nums2.size();
        if(m*n == 0)
        {
            if(m)
            {
                if(m%2 == 0)
                return double(nums1[nums1.size()/2-1]+nums1[nums1.size()/2])/2;
                else
                return nums1[nums1.size()/2];
            }
            else
            {
                if(n%2 == 0)
                return double(nums2[nums2.size()/2-1]+nums2[nums2.size()/2])/2;
                else
                return nums2[nums2.size()/2];    
            }
        }
        int k = (m+n+1)/2;
        if(k == 0)
        {
            if(m)
            return nums1[0];
            else
            return nums2[0];
        }
        double res = 0;
        int m1 = 0;
        int n1 = 0;
        while(k>1)
        {
            //cout<<"good"<<endl;
            //比较当前位置大小
            if(m1+k/2-1<m && n1+k/2-1<n)
            {
                
                if(nums1[m1+k/2-1] <= nums2[n1+k/2-1])
                m1+=k/2;
                else
                n1+=k/2;
                //cout<<k<<endl;
                //cout<<k/2<<endl;
                k = k-k/2;
            }
            else if(m1+k/2-1>=m)
            {
                if(nums1[m-1] <= nums2[n1+k/2-1])
                {
                    k = k-(m-m1);
                    res+=nums2[n1+k-1];
                    if((m+n)%2 == 0)
                    {
                        res+=nums2[n1+k];
                        res/=2;
                    }
                    return res;
                }
                else
                {
                    n1+=k/2;
                    k = k-k/2;
                }
            }
            else
            {
                if(nums1[m1+k/2-1] <= nums2[n-1])
                {
                    m1+=k/2;
                    k = k-k/2;
                }
                else
                {
                    k = k-(n-n1);
                    res+=nums1[m1+k-1];
                    if((m+n)%2 == 0)
                    {
                        res+=nums1[m1+k];
                        res/=2;
                    }
                    return res;
                }
            }
            //判断是否有序列到最后了
            if(m1>=m)
            {
                cout<<"good"<<endl;
                n1+=k-1;
                res+=nums2[n1];
                if((m+n)%2 == 0)
                {
                    res+=nums2[n1+1];
                    res/=2;
                }
                return res;
            }
            else if(n1>=n)
            {
                m1+=k-1;
                res+=nums1[m1];
                if((m+n)%2 == 0)
                {
                    res+=nums1[m1+1];
                    res/=2;
                }
                return res;
            }
        }
        if(m1>=m)
        {
            res+=nums2[n1];
            n1++;
        }
        else if(n1>=n)
        {
            res+=nums1[m1];
            m1++;
        }
        else if(nums1[m1]<=nums2[n1])
        {
            res+=nums1[m1];
            m1++;
        }
        else
        {
            res+=nums2[n1];
            n1++;
        } 
        if((m+n)%2 == 0)
        {
            if(m1>=m)
            res+=nums2[n1];
            else if(n1>=n)
            res+=nums1[m1];
            else
            {
                if(nums1[m1]<=nums2[n1])
                res+=nums1[m1];
                else
                res+=nums2[n1];
            }
            res/=2;            
        } 
        return res;     
    }
};

细节很难搞,果然和二分查找有关的都很难搞。

posted @ 2022-01-18 21:55  zhaohhhh  阅读(37)  评论(0)    收藏  举报