Median of Two Sorted Arrays

xiaoxiao2021-02-28  108

Median of Two Sorted Arrays

计算机中的算法到底研究的是技巧还是一种思维方式。

分析算法已知条件如下: - 两个有序数组 - 中位数:奇数取中间值偶数取中间两个数的平均数(浮点型)


直接思路

public class Solution { public double findMedianSortedArrays(int[] nums1, int[] nums2) { int length=nums1.length+nums2.length; boolean odd=length%2==1; int index=0; if(odd){ index=length/2; }else{ index=length/2-1; } System.out.print(index); return intAtIndex(nums1,nums2,index,odd); } public double intAtIndex(int[] nums1,int[] nums2,int index,boolean odd){ int temp=0; int left=0; int right=0; double result=0; while(temp<index){ if(left<nums1.length&&right<nums2.length&&nums1[left]<nums2[right]){ left++; }else if(left==nums1.length){ right++; }else if(right==nums2.length){ left++; }else{ right++; } temp++; } if(odd){ if(left==nums1.length){ result=nums2[right]; }else if(right==nums2.length){ result=nums1[left]; }else{ result=nums1[left]<nums2[right]?nums1[left]:nums2[right]; } }else{ String temp1=findNext(nums1,nums2,left,right); String[] temps=temp1.split(","); Integer leftNumber=Integer.parseInt(temps[0]); String temp2=findNext(nums1,nums2,Integer.parseInt(temps[1]),Integer.parseInt(temps[2])); Integer rightNumber=Integer.parseInt(temp2.split(",")[0]); result=(leftNumber+rightNumber)/2.0; } return result; } private String findNext(int[] nums1,int[] nums2,int left,int right){ int result=0; if(left==nums1.length){ result= nums2[right]; right++; } else if(right==nums2.length){ result= nums1[left]; left++; }else if(nums1[left]<nums2[right]){ result=nums1[left]; left++; }else{ result= nums2[right]; right++; } return result+","+left+","+right; } }

报错:运行时间超时。在本程序中已经尽量只遍历对数组只遍历一次,能优化的点只有第三个函数。

本以为时间复杂度为O(n)的算法已经接近极致了,没想到其实对有序数列来说O(logN),O(1)都是可以优化的目标。到网上翻了一些算法解决方案,主要思路如下:

将找中位数抽象为找第k小的数,既然已经告知两个数组有序,那就要充分利用此有效信息,减少算法的遍历范围。缩小范围从二分法开始:两边同时二分法,A[k/2]与B[k/2]进行比较,较小者的前半段可以不再比较,以此类推,逐渐跳跃式的减少对搜索空间的遍历。

看到我的第三个函数我只想说业务代码写多了,脑子里都是渣呀。优化后的算法如下:

public class Solution { public double findMedianSortedArrays(int A[], int B[]) { int len = A.length + B.length; if (len % 2 == 1) { return findKth(A, 0, B, 0, len / 2 + 1); } return ( findKth(A, 0, B, 0, len / 2) + findKth(A, 0, B, 0, len / 2 + 1) ) / 2.0; } // find kth number of two sorted array public static int findKth(int[] A, int A_start, int[] B, int B_start, int k){ if (A_start >= A.length) { return B[B_start + k - 1]; } if (B_start >= B.length) { return A[A_start + k - 1]; } if (k == 1) { return Math.min(A[A_start], B[B_start]); } int A_key = A_start + k / 2 - 1 < A.length ? A[A_start + k / 2 - 1] : Integer.MAX_VALUE; //此处为算法的技巧点, //本质比较的是第k/2个数,当index越界时,认为其中位数为最大整数,不在此轮进行比较A数组的元素,而是去比较B数组的元素,从而减小K的取值。 //最大整数的引用,可以规范算法的形式,思想以后可以借鉴 int B_key = B_start + k / 2 - 1 < B.length ? B[B_start + k / 2 - 1] : Integer.MAX_VALUE; if (A_key < B_key) { return findKth(A, A_start + k / 2, B, B_start, k - k / 2); } else { return findKth(A, A_start, B, B_start + k / 2, k - k / 2); } } }

优化算法来源:http://www.jiuzhang.com/solutions/median-of-two-sorted-arrays/

转载请注明原文地址: https://www.6miu.com/read-29018.html

最新回复(0)