LeetCode代码分析——4. Median of Two Sorted Arrays
2016-04-14 15:37
435 查看
一道找中间数的题,两个排序好的数组
最简单粗暴的方法很容易,就是搞个排序(归并分治策略的最后一步合并两个排序好的数组?or快排?),然后找到(m+n)/2位置的数
下面这种思想认为找中间数就是找第k = (m+n)/2大的数,找两个数组合起来后第k大的数,分别看A数组和B数组中间(k/2)位置的数,小的数的左半部分可以抛弃,然后剩下的再找。。。直到第一个数组被掏空(就直接找第二个的k位置,注意只可能是第一个数组被掏空,因为第一个数组一定比第二个数组短,如果不是的话A,B是会互换的),或者前面的部分已经被抛弃完只能找第一个(比较A和B的第一个),或者发现A和B的中点相等(那就直接返回这个相等的数)
最简单粗暴的方法很容易,就是搞个排序(归并分治策略的最后一步合并两个排序好的数组?or快排?),然后找到(m+n)/2位置的数
下面这种思想认为找中间数就是找第k = (m+n)/2大的数,找两个数组合起来后第k大的数,分别看A数组和B数组中间(k/2)位置的数,小的数的左半部分可以抛弃,然后剩下的再找。。。直到第一个数组被掏空(就直接找第二个的k位置,注意只可能是第一个数组被掏空,因为第一个数组一定比第二个数组短,如果不是的话A,B是会互换的),或者前面的部分已经被抛弃完只能找第一个(比较A和B的第一个),或者发现A和B的中点相等(那就直接返回这个相等的数)
public class Solution { public double findMedianSortedArrays(int[] nums1, int[] nums2) { int m = nums1.length; int n = nums2.length; int size = m + n; if(size % 2 == 1){ return findKth(nums1, 0, m, nums2, 0, n, size/2 + 1); } else{ return (findKth(nums1, 0, m, nums2, 0, n, size/2) + findKth(nums1, 0, m, nums2, 0, n, size/2 + 1)) / 2; } } public double findKth(int[] nums1,int s1, int m, int[] nums2,int s2, int n, int k){ //假定nums1永远比nums2短 if(m > n){ return findKth(nums2, s2 , n, nums1, s1, m, k); } else if(m == 0){ return nums2[s2 + k - 1]; } else if(k == 1){ return nums1[s1] < nums2[s2] ? nums1[s1] : nums2[s2]; } //A = {1,3,5} B = {2,4,6,8} 共7个,找第四个,找A里面的第二个,B里面的第二个, //3 < 4,(反证)假设3是整个里面第五个,那么A里面最多一个比3小,B里面最多1个比3小,才两个,根本不够凑足4个 //所以3一定是在第四个之前,所以可以抛弃掉3和它之前的部分 int pa = k/2 < m? k/2 : m; int pb = k - pa; //如果A的第pa个数小,那么抛弃掉A前面那些,B不变,这样就少了前pa个, //找k-pa个(找第三名,前两名死了,想找第三名就成了找剩下人里的第一名了) if(nums1[s1 + pa - 1] < nums2[s2 + pb - 1]){ return findKth(nums1, s1 + pa, m - pa, nums2, s2, n, k - pa); } else if(nums1[s1 + pa - 1] > nums2[s2 + pb - 1]){ return findKth(nums1, s1, m, nums2, s2 + pb, n - pb, k - pb); } //A = {1,3,5} B = {2,3,6,8} 同上,这时A里面的第二个,B里面的第二个都是3, //总体是{1,2,3,3,5,6,8},3可以算是在3的前面,这样3前面有1个,3前面有1个,3前面可以说有个3, //找第四个,刚好前面有三个,刚好就是。所以相等的情况下可以直接返回 //else if(nums1[s1 + pa - 1] == nums2[s2 + pb - 1]){ else{ return nums1[s1 + pa - 1]; } } }
相关文章推荐
- Java之获取表字段名
- 用goto语句写的带父节点的中序遍历
- C语言中#define的用法(转)
- ASP.NET-JSON.NET技巧
- Java设计模式(三) Visitor(访问者)模式及多分派场景应用
- C++经典面试题之---String类
- Java下利用Jackson进行JSON解析和序列化
- python模块: OS模块
- Java多线程——java.util.concurrent库中的CyclicBarrier和CountDownLatch工具
- spring+ibatis+多数据源
- jrtplib简介
- 适用于WebForm Mvc的Pager分页组件C#实现
- python——Django(ORM连表操作)
- Django开发环境搭建
- PHP时间日期操作增减(date strtotime) 加一天 加一月
- Java中的弱引用
- World Wind Java开发 加载三维模型
- Java SPI机制
- 页面生成带有合计的表格
- Struts2---标签