4寻找两个正序数组中的中位数

方法一:暴力求解
先把两个数组合成一个大数组,进行快排,最后中位数,思路清晰,但是时间复杂度较高,为O(m+n)log(m+n)
方法二:合并排序
等我做完第88题回来补充
方法三:二分查找
运用递归思想,写一个函数查找两个数组中第k小的元素,方法是比较两个数组中第k/2个元素,小的那个和其前面的数一定不是第k小的元素,一直递归到其中一个数组为空或者k等于1

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
/*
  比较原始的想法,先合并两个数组,然后排序,最好找中位数
*/
class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        vector<int>a;
        int n = nums1.size();
        int y = nums2.size();
        for (int i = 0; i < n; i++)
        {
            a.push_back( nums1[i]);
        }
        for (int i=0; i < y; i++)
        {
            a.push_back(nums2[i]);
        }
        sort(a.begin(), a.end());//用一个快排,时间复杂度为O(m+n)log(m+n)
        int m = a.size();
        if (m % 2 == 1)
        {
            return a[(m - 1) / 2];
        }
        else
        {
            double d;
            d =((double)(a[m / 2 - 1]) + (double)(a[m / 2])) / 2;
            return d;
        }
    }
};
class Solution1 {
public:
    //找到第k小的数,递归
    int getKthElement(const vector<int>& nums1, const vector<int>& nums2, int k) {
        int m = nums1.size();
        int n = nums2.size();
        int index1 = 0; int index2 = 0;//index为本次经删除数组的0号位置
        while (true)
        {
            //三种特殊情况:两个数组有一个空了,直接输出另一个数组的第k小;或者k=1,直接输出两个数组开头元素的较小者
            if (index1 == m)
            {
                return nums2[index2 + k - 1];
            }
            if (index2 == n)
            {
                return nums1[index1 + k - 1];
            }
            if (k == 1)
            {
                return min(nums1[index1], nums2[index2]);
            }
            //正常情况
            //newindex代表该数组中第k/2-1的元素的指针
            int newindex1 = min(index1 + k / 2 - 1, m - 1);
            int newindex2 = min(index2 + k / 2 - 1, n - 1);
            int pivot1 = nums1[newindex1];
            int pivot2 = nums2[newindex2];
            //删除较小者及其前面的元素,指针后移
            if (pivot1 <= pivot2)
            {
                k = k - (newindex1 - index1 + 1);
                index1 = newindex1 + 1;
            }
            else
            {
                k = k-(newindex2 - index2 + 1);
                index2 = newindex2 + 1;
            }
        }
    }
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int totallength = nums1.size() + nums2.size();
        if (totallength % 2 == 1)
        {
            return getKthElement(nums1, nums2, (totallength + 1) / 2);
        }
        else
        {
            return (getKthElement(nums1, nums2, totallength / 2) + getKthElement(nums1, nums2, totallength / 2 + 1)) / 2.0;
            //除以2.0,隐式转换为double
        }

    }
};
int main()
{
    Solution1 test;
    vector<int>nums1 = { 1, 3 };
    vector<int>nums2 = { 2 ,4};
    cout << test.findMedianSortedArrays(nums1, nums2);
}
————————————————分割线————————————————————————————————
补充了一下合并排序,双指针做法

```cpp
#include<iostream>
#include<vector>
using namespace std;
class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        vector<int>a;
        int m = nums1.size();
        int n = nums2.size();
        int index1 = 0;
        int index2 = 0;
        while (index1 < m || index2 < n)
        {
            if (index1 >= m)
            {
                a.push_back(nums2[index2]);
                index2++;
            }
            else if (index2 >= n)
            {
                a.push_back(nums1[index1]);
                index1++;
            }
            else
            {
                if (nums1[index1] <= nums2[index2])
                {
                    a.push_back(nums1[index1]);
                    index1++;
                }
                else
                {
                    a.push_back(nums2[index2]);
                    index2++;
                }
            }
        }
        if (a.size() % 2 == 1)
        {
            return a[(a.size() - 1) / 2];
        }
        else
        {
            return(a[a.size() / 2 - 1] + a[a.size() / 2]) / 2.0;
        }
    }
};
int main()
{
    Solution test;
    vector<int>nums1 = { 1,3 };
    vector<int>nums2 = { 2};
    cout << test.findMedianSortedArrays(nums1,nums2);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值