leetcode 4 Median of Two Sorted Arrays
来源:互联网 发布:天天飞车礼包 软件 编辑:程序博客网 时间:2024/06/05 03:31
Median of Two Sorted Arrays
Total Accepted: 59220 Total Submissions: 345234There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
首先说明一下,两个数列的中位数(median),就是把两个数列合在一起后,从小到大排列,位于中间的数,如果总的长度是奇数,那么中位数就是一个数,否则中位数就是中间两个数的平均数。这个题
但题目要求要
double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) { double median; int total = nums1Size + nums2Size; if(total % 2 == 0) { median = (findKthElement(nums1, nums1Size, nums2, nums2Size, total/2) + findKthElement(nums1, nums1Size, nums2, nums2Size, total/2+1)) / 2; } else { median = findKthElement(nums1, nums1Size, nums2, nums2Size, total/2+1); } return median;}
这个函数起始很简单,实现的功能就是之前描述的:如果总的长度是奇数,那么中位数就是第
double findKthElement(int* nums1, int nums1Size, int* nums2, int nums2Size, int k){ double KthElement; if(nums1Size > nums2Size) KthElement = findKthElement(nums2, nums2Size, nums1, nums1Size, k); else if(nums1Size == 0) { KthElement = nums2[k-1]; } else if(k == 1) { KthElement = nums1[0] < nums2[0] ? nums1[0] : nums2[0]; }
首先我们要判断数组nums1和nums2哪个长,我们默认是nums2长于等于nums1,所以如果nums1长于nums2,那么我们就用递归的方式把两个数组交换位置。之所以保证nums1短于nums2,是因为我们后面的又操作时针对短的数组进行的,如果不确定哪个短,每次就都需要进行判断,代码就变得冗长。另外,我们要处理两种特殊情况,第一种是有一个数组为空,这是可能的,因为我们后面的算法会进行“删除”操作,因此数组可能变为空。这种情况下,我们要求第k小的元素,那显然就是剩下这个非空数组的第k小的元素,所以就是nums2[k-1],因为nums1比nums2短,所以非空的一定是nums2。另外一种情况,我们要求的是最小的元素,由于两个数列都是按升序排好了的,所以只需要比较nums1[0]和nums2[0],选择较小的那个即可。
else { int i1 = min(nums1Size, k/2); if(nums1[i1-1] < nums2[k-i1-1]) { KthElement = findKthElement(nums1+i1, nums1Size-i1, nums2, nums2Size, k-i1); } else if(nums1[i1-1] > nums2[k-i1-1]) { KthElement = findKthElement(nums1, nums1Size, nums2+k-i1, nums2Size-(k-i1), i1); } else { KthElement = nums1[i1-1]; } } return KthElement;}
其他的情况,我们要求i1,i1表示我们要求nums1中的第i1小的元素和nums2中的第k-i1小的元素,这两个元素是一定存在的,当i1等于nums1Size时,因为要求第k小,所以两数组的总数必然大于等于k,所以nums2Size必然大于等于k-nums1Size,所以nums2中必然包含大于等于k-i1(即k-nums1Size)个元素。当nums1等于
我们要取两者的较小值,因为我们是要在两个数组总共取k个值,所以默认是各取
我们现在已经取到了nums1中第i1小的数和nums2中第k-i1小的数,分别对应是数组中的nums1[i1-1]和nums2[k-i1-1]。然后我们来比较这两个数的大小,如果nums1[i1-1]
因此我们可以“删除”或者说忽略掉nums1中的这前i1个数,然后问题转化为:求从nums1中的第i1+1个数开始的剩下的数列和nums2数列合并后的第k-i1小的数。而这个数就是nums1和nums2合并后的第k小的数。这一点可以证明如下:如果求出来的这个第k-i1小的数(假设为a)来自nums1,那么它必然大于等于nums1中的前i1个数,所以把被忽略掉的这i1个数重新添加回去后,它们也都排在a的前面,所以a就变成第k小的数。如果求出来的数来自nums2,分两种情况:1. a前面k-i1个数中没有nums1的元素,那么a就是nums2里面的第k-i1小的元素,因为我们已知nums1[i1-1]
如果nums1[i1-1]
另外,如果nums1[i1-1]=nums2[k-i1-1],那么这个值就是我们要找的第k小的元素。以nums1[i1-1]为例,nums2的前k-i1个元素全部可以放到它前面。nums2从第k-i1+1开始的元素全部可以放到它后面,因此它就是第k小的元素。
这个算法的好处就是每次比较后都能忽略掉一部分,使问题得规模减小,但并不是每次都减半,所以是否能够做到
下面附上完整代码:
#include <iostream>#include <stdlib.h>using namespace std;#define min(x,y) x<y?x:ydouble findKthElement(int* nums1, int nums1Size, int* nums2, int nums2Size, int k){ double KthElement; if(nums1Size > nums2Size) KthElement = findKthElement(nums2, nums2Size, nums1, nums1Size, k); else if(nums1Size == 0) { KthElement = nums2[k-1]; } else if(k == 1) { KthElement = nums1[0] < nums2[0] ? nums1[0] : nums2[0]; } else { int i1 = min(nums1Size, k/2); if(nums1[i1-1] < nums2[k-i1-1]) { KthElement = findKthElement(nums1+i1, nums1Size-i1, nums2, nums2Size, k-i1); } else if(nums1[i1-1] > nums2[k-i1-1]) { KthElement = findKthElement(nums1, nums1Size, nums2+k-i1, nums2Size-(k-i1), i1); } else { KthElement = nums1[i1-1]; } } return KthElement;}double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) { double median; int total = nums1Size + nums2Size; if(total % 2 == 0) { median = (findKthElement(nums1, nums1Size, nums2, nums2Size, total/2) + findKthElement(nums1, nums1Size, nums2, nums2Size, total/2+1)) / 2; } else { median = findKthElement(nums1, nums1Size, nums2, nums2Size, total/2+1); } return median;}int main(){ cout<<"Input the size of nums1:"<<endl; int nums1Size; cin>>nums1Size; int *nums1 = (int*)malloc(sizeof(int) * nums1Size); int temp; for(int i = 0; i < nums1Size; i++) { cin>>temp; nums1[i] = temp; } cout<<"Input the size of nums2:"<<endl; int nums2Size; cin>>nums2Size; int *nums2 = (int*)malloc(sizeof(int) * nums1Size); for(int i = 0; i < nums2Size; i++) { cin>>temp; nums2[i] = temp; } cout<<findMedianSortedArrays(nums1, nums1Size, nums2, nums2Size)<<endl; return 0;}
- Leetcode 4 Median of Two Sorted Arrays
- LeetCode 4 - Median of Two Sorted Arrays
- Leetcode 4 Median of Two Sorted Arrays
- Leetcode 4 Median of Two Sorted Arrays
- [leetcode 4] Median of Two Sorted Arrays
- LeetCode 4:《Median of Two Sorted Arrays》
- [Leetcode] 4 - Median of Two Sorted Arrays
- leetcode|4|Median of Two Sorted Arrays
- [Leetcode]4Median of Two Sorted Arrays
- leetcode 4 Median of Two Sorted Arrays
- LeetCode #4 Median of Two Sorted Arrays
- LeetCode-4-Median of Two Sorted Arrays
- LeetCode 4 Median of Two Sorted Arrays
- leetcode 4 Median of Two Sorted Arrays
- LeetCode 4 Median of Two Sorted Arrays
- Leetcode[4] Median of Two Sorted Arrays
- LeetCode 4 - Median of Two Sorted Arrays
- leetcode 4 -- Median of Two Sorted Arrays
- NET下RabbitMQ实践[实战篇]
- Linux下进程间通信概述
- C++ Memory Management C++ 内存管理
- SWF代码分析与破解之路 (YueTai VIP视频信息获取工具) Socket续篇
- [LeetCode.Trick]Rotate Array
- leetcode 4 Median of Two Sorted Arrays
- 驱动的io端口的申请,注册中断
- GitHub上史上最全的Android开源项目分类汇总
- ds18b20驱动终于写好了
- LeetCode 题解(159): Partition List
- CodeForces 429B()
- 多线程
- 【LeetCode-面试算法经典-Java实现】【113-Path Sum II(路径和)】
- 【LeetCode-面试算法经典-Java实现】【114-Flatten Binary Tree to Linked List(二叉树转单链表)】