MedianOfTwoSortedArrays
来源:互联网 发布:软件工程学什么 编辑:程序博客网 时间:2024/06/06 13:07
git
package com.leetcode;/** * Created by RayDu on 2017/9/2. */public class MedianOfTwoSortedArrays { /** * 17/9/22 * 解题思路: * * 这道题的时间复杂度要求是:O(log(m+n)),直觉上觉得使用类似于二分查找的方式来做效果应该不错,对于我自己的难点在于 * 1.对于中点是第多少大的数、下标应该是多少 * 2.二分查找的终止条件是什么 * 3.有什么边界条件需要考虑 * * 一、整体思路 * 比如: * a :a[0]=1 a[1]=2 a[2]=3 a[3]=4 a[4]=5 a[5]=6 a[6]=7 * b :b[0]=2 b[1]=4 b[2]=5 b[3]=7 b[4]=8 b[5]=9 b[6]=10 * 这里我们知道, * 如果 a[3] < b[3],我们可以说max(a[3],b[3])是两组数列左边最大的数,如果这个值小于min(a[4],b[4]) * 那么max(a[3],b[3])就是整组数(a、b)中第6个数。 * 所以 * 1.我们需要找一个约束条件,比如 有a[i],b[j] i+j = k (常数) 这样我们改变i的值,j就可以根据约束条件改变了 * 2.如何保证 max(a[i],b[j])就是第k个数呢? 只需保证在满足1的约束条件下 max(a[i],b[j]) < min(a[i+1],b[j+1]) 当然这里肯定有边界条件需要考虑 * 3.然后就是如何搜索的问题了,其实就是找在约束条件1下,满足条件2的组合,这里的停止条件自然是:要么搜索到最后一个了,要么条件2被满足~ * * 二、下标问题 * 前面一直在说第k大的数,其实困扰最久的问题是约束条件的构造:median of xxx ,到底是第k(k=?)的数呢? * 这是一个蛮关健的约束条件 * * 假设一个数组长 m * 中间的那个数的下标是(从0起): m/2 (m-1)/2 --> 也就是说"一半"有: m/2个 * eg 对于5:0,1,[2],3,4 5/2 = 2[下取整] 4/2 = 2 * 对于8: 0,1,2,[3],[4],5,6,7 8/2 = 4 7/2 = 3 * * 对于这道题,假设两个数组是m,n长度的数组, 那么中间的数下标是 (m+n)/2,(m+n-1)/2 他们所包含的子数组长度是 (m+n+2)/2 (m+n+1)/2 * 这里我们其实只用讨论其中一个长度即可,假设我们讨论(m+n+1)/2,假设我们有一个无形的分割线 * a[0] ... a[i] | a[i+1] .... a[m-1] * b[0] ... b[j] | b[j+1] .... b[n-1] * 如果说那么左侧的个数是: i + 1 + i + 1 = (m+n+1)/2 * 我们知道max(a[i],a[j])就是第(m+n+1)/2 大的数 * 边界情况: i = -1/j = -1 -> 整个a/b数组都在大的一侧, 此时 b[j]/a[i] 是第k个数 * i = m-1/j = n-1 -> 整个数组都在小的一侧,若需要求(m+n+2)/2 则是b[j+1]/a[i+1] * * 上面我们其实是在看小的那部分的max,同样的我们可以关注大的那部分的min,那么我们可以换一个视角来看: * a[0] ... a[i-1] | a[i] .... a[m-1] * b[0] ... b[j-1] | b[j] .... b[n-1] * 同样的,左侧个数是 (i-1)+1 + (i-1)+1 = (m+n+1)/2 * 边界情况变成了i = 0/j = 0 以及 i=m/j=n * * 三、二分查找的思路: * * 初始: min = -1,max = s1.length-1 * 迭代: * i = (min+max)/2 * j = (m+n+1)/2 - 2 - i * * 我们希望有 max(s1[i],s2[j]) <= min(s1[i-1],s2[j-2]) * 事实上,不一定遂人愿 * 如果说: s1[i]>s2[j+1] 则说明i需要减小,所有i以后的都不可以 * 如果说: s1[i+1]<s2[j] 则说明i需要增大,所有i以前的都不可以 * 如果说: s1[i]<=s2[j+1] && s2[j]<=s1[i+1],则满足条件 * * 四、最后说一个小技巧 * 如果我们二分的字符串是长的那个,可能就会出现短的那个下标越界的情况,为了避免这个情况,我们可以在一开始就 * 做一些操作,确保是用的短的数组做二分 * */ public static double findMedianSortedArrays(int[] nums1, int[] nums2) { int[] tmp; if(nums1.length > nums2.length){ tmp = nums1; nums1 = nums2; nums2 = tmp; } //注意这里不能直接-3,因为会有整数的精度问题 int half = (nums1.length + nums2.length + 1)/2; int min = -1; int max = nums1.length - 1; while (min<=max){ int i = (min + max) / 2; int j = half - 2 - i ; if( i<max && nums1[i+1] < nums2[j]){ //这里有一个问题,按理说 min = i + 1 更快?可实时不是这样的 min = min + 1; }else if(i > min && nums1[i] > nums2[j+1]){ max = max - 1; }else { int left = 0; if(i == -1)left = nums2[j]; else if(j == -1)left = nums1[i]; else left = Math.max(nums1[i],nums2[j]); if((nums1.length+nums2.length)%2 == 1)return left; int right = 0; if(i==nums1.length - 1)right=nums2[j+1]; else if(j==nums2.length - 1)right=nums1[i+1]; else right=Math.min(nums1[i+1],nums2[j+1]); return (right+left)/2.0; } } return 0.0; } public static void main(String[] args){ int[] a ={3,4,5,8,10}; int[] b ={1,2,6,7,9}; System.out.print(findMedianSortedArrays(a,b)); }}
阅读全文
0 0
- MedianOfTwoSortedArrays
- leetcode4.MedianofTwoSortedArrays
- 4.MedianOfTwoSortedArrays
- leetcode解题方案--004--MedianofTwoSortedArrays
- RSA的实现原理
- Linux
- select 的onchange方法失效问题
- 神经网络中梯度下降算法原理
- Android 实现根据录音分贝画波浪线
- MedianOfTwoSortedArrays
- JS 获取String转数组
- 三个方法实现求两个数的最大公约数
- Facebook 内部如何看待此次 React 专利事件?
- java学习建议(转)
- 单例
- BZOJ 1858 [Scoi2010]序列操作
- Java上机心得2
- 提高HBase WAL写入性能