方法一:暴力求解
先把两个数组合成一个大数组,进行快排,最后中位数,思路清晰,但是时间复杂度较高,为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);
}