Leetcode:Median of Two Sorted Arrays
2015-07-31 16:21
483 查看
Question
There 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)).Solution
方案一:将两个数组合成一个数组,使用快速排序算法进行排序,然后找到中位数。空间复杂度:
O(m+n)O(m+n)
时间复杂度:
O(log(m+n))O(log(m+n))
方案二:对nums1和nums2数组分别使用二分查找法,直到最后两个数组剩下一个或两个元素,这样就很容易找到中位数。
空间复杂度:
O(1)O(1)
时间复杂度:
O(log(max(m,n))O(log(max(m, n))
方案一代码:
这里我没有自己编写快速排序算法,使用的是python的内建函数。最后的平均速度是124ms。
class Solution: # @param {integer[]} nums1 # @param {integer[]} nums2 # @return {float} def findMedianSortedArrays(self, nums1, nums2): alln = nums1 + nums2 alln.sort() maxn = len(alln) if maxn % 2 == 1: return alln[maxn/2] else: return ( alln[maxn/2] + alln[maxn/2 - 1] ) / 2.0
方案二代码:
这里的代码总是又几个数据不能运行,所以这个暂时先放一放,代码我就暂时不贴上来了。
其他人的解决方案
C语言double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) { int left = (nums1Size + nums2Size + 1) / 2, right = left; if((nums1Size + nums2Size) % 2 == 0) right++; //printf("left:%d\tright:%d\n", left, right); //find the left smallest element, comparing from the start of array--O(left) //BETTER: left/2, left/4, left/8... int i = 0, j = 0, t = left, k = (t + 1) / 2; while(k > 0) { if(i + k > nums1Size || j + k > nums2Size) break; if(nums1[i+k-1] < nums2[j+k-1]) i += k; else j += k; t -= k; k = (t + 1) / 2; } while(t > 0 && i < nums1Size && j < nums2Size) { if(nums1[i] < nums2[j]) i++; else j++; t--; } if(t > 0) { if(i == nums1Size) j += t; else if(j == nums2Size) i += t; } int mid_left, mid_right; if(i > 0 && j > 0) mid_left = (nums1[i-1] < nums2[j-1])?nums2[j-1]:nums1[i-1]; else if(i == 0) mid_left = nums2[j-1]; else if(j == 0) mid_left = nums1[i-1]; if(right > left) { if(i < nums1Size && j < nums2Size) mid_right = (nums1[i] < nums2[j])?nums1[i]:nums2[j]; else if(i == nums1Size) mid_right = nums2[j]; else if(j == nums2Size) mid_right = nums1[i]; } else mid_right = mid_left; //printf("mid_left:%d\tmid_right:%d\n", mid_left, mid_right); return (mid_left + mid_right) / 2.0; }
C++代码
public: double findMedianSortedArrays(vector<int>& nums1,vector<int>& nums2) { int m,n,k; m = nums1.size(); n = nums2.size(); auto beg1 = nums1.begin(),beg2 = nums2.begin(); k = (m+n)>>1; if((m+n) & 0x1) return find_kth(nums1,beg1,nums2,beg2,k+1); else return (find_kth(nums1,beg1,nums2,beg2,k) + find_kth(nums1,beg1,nums2,beg2,k+1))/2.0; } private: double find_kth(vector<int>& nums1,vector<int>::iterator beg1,vector<int>& nums2,vector<int>::iterator beg2,int k) { int m = nums1.end() - beg1,n = nums2.end() - beg2; if(m>n) return find_kth(nums2,beg2,nums1,beg1,k); if(m==0) return *(beg2+k-1); if(k==1) return min(*beg1,*beg2); int m1 = min(k/2,m),m2 = k-m1; if(*(beg1+m1-1)<*(beg2+m2-1)) return find_kth(nums1,beg1+m1,nums2,beg2,k-m1); else if(*(beg1+m1-1)>*(beg2+m2-1)) return find_kth(nums1,beg1,nums2,beg2+m2,k-m2); else return *(beg1+m1-1); }
Java代码
int l1 = -1; int l2 = -1; public double findMedianSortedArrays(int[] nums1, int[] nums2) { int tar = (nums1.length + nums2.length); if (nums1.length * nums2.length == 0) { if (nums1.length == 0) { if (tar % 2 == 0) return (nums2[nums2.length / 2 - 1] + nums2[nums2.length / 2]) / 2.0; return nums2[nums2.length / 2]; } else { if (tar % 2 == 0) return (nums1[nums1.length / 2 - 1] + nums1[nums1.length / 2]) / 2.0; return nums1[nums1.length / 2]; } } if (tar % 2 == 0) { return (find(tar / 2 - 1, nums1, nums2) + find(0, nums1, nums2)) / 2.0; } else { return find(tar / 2, nums1, nums2); } } public int find(int next, int[] nums1, int[] nums2) { if (next == 0) { if (l1 == nums1.length - 1) { return nums2[l2++ + 1]; } else if (l2 == nums2.length - 1) { return nums1[l1++ + 1]; } return nums1[l1 + 1] > nums2[l2 + 1] ? nums2[l2++ + 1] : nums1[l1++ + 1]; } if (next == 1) { if (nums1[l1 + 1] > nums2[l2 + 1]) { l2++; } else { l1++; } return find(0, nums1, nums2); } else { int t1 = (next - 2) / 2 % (nums1.length - 1 - l1) + 1; int t2 = (next - 2) / 2 % (nums2.length - l2 - 1) + 1; if (nums1[l1 + t1] >= nums2[t2 + l2]) { if (t2 + l2 == nums2.length - 1) { next = next - t2; l2 = t2 + l2; l1 = l1 + next; return nums1[l1++ + 1]; } else { next = next - t2; l2 = t2 + l2; return find(next, nums1, nums2); } } else { if (t1 + l1 == nums1.length - 1) { next = next - t1; l1 = t1 + l1; l2 = l2 + next; return nums2[l2++ + 1]; } else { next = next - t1; l1 = t1 + l1; return find(next, nums1, nums2); } } } }
Summarizes
这一道题我花了很长时间,知道对两个数组使用折半搜索,但是最后的地方总是想不明白。内建函数是经过优化的,所以速度会比自己写的函数要快很多,以后如果能使用内建函数的地方,最好还是使用内建函数。相关文章推荐
- NSTimer
- 王者归来-上
- java中import机制(指定import和import *的区别)
- python数据结构与算法——链表
- cocos2d-x博客网站推荐和牛逼的教程
- SQL Server存储过程中执行动态SQL语句
- Object-C 中的日期(NSDate)
- 匹配算法·温故知新——二分图的最大(基数)匹配
- 构造简单好用的年份、年月选择器
- 成绩查询系统Java版-我们要做的还有很多
- 苹果个人开发者账号如何升级成公司账号
- 升级Windows10![收不到Win10升级预订通知的解决办法]
- ZOJ - 2412 Farm Irrigation
- 手机自动化执行一段时间后中断
- Error:Cannot build Artifact :war exploded because it is included into a circular depency
- 将double类型转换为整形,并且只有小数点后有值就进1
- 构造简单好用的年份、年月选择器
- 推荐几本学习嵌入式linux的书籍
- 迷宫问题的反思
- C++学习笔记——类和对象(三)