LeetCode4:两个排序数组的中位数
Posted 爆米花好美啊
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode4:两个排序数组的中位数相关的知识,希望对你有一定的参考价值。
问题
/*
* @lc app=leetcode.cn id=4 lang=cpp
* * [4] 寻找两个有序数组的中位数
* * https://leetcode-cn.com/problems/median-of-two-sorted-arrays/description/
* * algorithms
* Hard (33.60%)
* Total Accepted: 37K
* Total Submissions: 110.2K
* Testcase Example: '[1,3]\\n[2]'
* * 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。
*
* 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。
*
* 你可以假设 nums1 和 nums2 不会同时为空。
*
* 示例 1:
*
* nums1 = [1, 3]
* nums2 = [2]
*
* 则中位数是 2.0
*
*
* 示例 2:
*
* nums1 = [1, 2]
* nums2 = [3, 4]
*
* 则中位数是 (2 + 3)/2 = 2.5
*
*
*/
思路1:归并排序,合并有序数组,时间复杂度O(m+n),不符合要求
思路2:看到时间复杂度O(log(m+n)),首先可以想到二分法(分治思想)
-
把找中位数转化为找第 (m+n+1)/2 和 第 (m+n+2)/2 小元素的平均(这样不用考虑奇偶的问题)
-
二分思想设计find_kth函数 假定整体数组c中欧前k个元素一半k/2在数组a,一半k/2在数组b
- 如果a[k/2] < b[k/2] 那么 a[0]<=a[1]<=…<=a[k/2] <= b[k/2] 且 b[0]<=b[1]<=…<=b[k/2] 说明b[k/2] 至少是c中第k小的元素,所以a[0-k/2]都小于我们的目标值,可以去掉a[0-k/2],然后在剩下的元素中找第k/2小
- 同理如果a[k/2] > b[k/2] 所以b[0-k/2]都小于我们的目标值,可以去掉b[0-k/2],然后在剩下的元素中找第k/2小
-
如果数组a中个数不够k/2,那么b中小于目标元素的个数一定大于k/2,所以可以去掉b中前k/2小的元素,然后在剩下的元素中找第k/2小
-
同理如果数组b中个数不够k/2,那么a中小于目标元素的个数一定大于k/2,所以可以去掉a中前k/2小的元素,然后在剩下的元素中找第k/2小
完整代码如下
class Solution
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2)
int m = nums1.size();
int n = nums2.size();
if (nums1.empty())
if (n%2 != 0)
return 1.0*nums2[n/2];
return (nums2[n/2]+nums2[n/2-1])/2.0;
if (nums2.empty())
if (m%2 != 0)
return 1.0*nums1[m/2];
return (nums1[m/2]+nums1[m/2-1])/2.0;
int total = (m+n+1)/2;
int total2 = (m+n+2)/2;
// 转换为在两个有序数组中寻找第k小元素(从1计数) (m+n+1)/2 (m+n+2)/2
return (find_kth(nums1,0,nums2,0,total)+find_kth(nums1,0,nums2,0,total2))/2.0;
double find_kth(vector<int> a, int a_begin, vector<int> b, int b_begin, int k)
// a中无元素 b有序 直接在b中取第k小元素
if (a_begin > a.size()-1)
return b[b_begin+k-1];
if (b_begin > b.size()-1)
return a[a_begin+k-1];
// 第1小元素 就是找ab中最小元素的最小值
if (k == 1)
return min(a[a_begin],b[b_begin]);
if (a_begin+k/2-1 < a.size() && b_begin+k/2-1 < b.size())
if(a[a_begin+k/2-1] < b[b_begin+k/2-1])
return find_kth(a,a_begin+k/2,b,b_begin,k-k/2);
else
return find_kth(a,a_begin,b,b_begin+k/2,k-k/2);
else if(a_begin+k/2-1 < a.size())
return find_kth(a,a_begin+k/2,b,b_begin,k-k/2);
else
return find_kth(a,a_begin,b,b_begin+k/2,k-k/2);
以上是关于LeetCode4:两个排序数组的中位数的主要内容,如果未能解决你的问题,请参考以下文章
leetcode4. Median of Two Sorted Arrays