之前一直是写C++的,想着开始学学用JAVA写Code会有什么不同,是否会更加简洁?于是开始学着用JAVA去刷LEETCODE
习题如下:
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)).
Example 1:
nums1 = [1, 3] nums2 = [2] The median is 2.0
Example 2:
nums1 = [1, 2] nums2 = [3, 4] The median is (2 + 3)/2 = 2.5
最开始想到的解法比较大众,两个数组的中位数不外乎就是对两个数组合并排序后的中位数,如果m+n是偶数,那么中位数就是合并后的第(m+n)/2+1个元素,如果m+n是奇数,那么中位数就是第(m+n)/2-1和第(m+n)/2+1个数相加除以2.那么问题就变成把两个有序数组合并,当合并到第(m+n)/2个元素的时候返回那个数即可,而且不用把结果数组存起来。但是注意时间复杂度是O(m+n),不符合要求 优化算法:问题等价于求两个array的第k=(m+n)/2(假设m和n分别是两个数组的元素个数)大的数是多少。基本思路是每次通过查看两个数组的第k/2大的数(假设是A[k/2],B[k/2]),如果两个A[k/2]=B[k/2],说明当前这个数即为两个数组剩余元素的第k大的数,如果A[k/2]>B[k/2], 那么说明B的前k/2个元素都不是我们要的第k大的数,反之则排除A的前k/2个,如此每次可以排除k/2个元素,最终k=1时即为结果。总的时间复杂度为O(logk),空间复杂度也是O(logk),即为递归栈大小。在这个题目中因为k=(m+n)/2,所以复杂度是O(log(m+n))。 具体代码如下:
{ public double findMedianSortedArrays(int[] nums1, int[] nums2) { int m=nums1.length; int n=nums2.length; int total=m+n; if(total%2 == 0){ return (double)findKth(nums1,nums2,0,m-1,0,n-1,(m+n)/2+1); }else{ double temp1= findKth(nums1,nums2,0,m-1,0,n-1,(m+n)/2-1); double temp2= findKth(nums1,nums2,0,m-1,0,n-1,(m+n)/2+1); return (temp1+temp2)/2; } } public int findKth(int[] A,int[] B,int start_A,int end_A,int start_B,int end_B,int K){ int lengthA=end_A-start_A+1; int lengthB=end_B-start_B+1; if(lengthA > lengthB) return findKth(B,A,start_B,end_B,start_A,end_A,K); if(lengthA==0) return B(start_B+K-1); if(k==1) return Math.min(A[k],B[k]); Pos_A=Math(K/2,m); Pos_B=K-Pos_A; if(A[Pos_A]==B[Pos_B]) return A[start_A+Pos_A]; else if(A[Pos_A] > B[Pos_B]) return findKth(A,B,start_A,end_A,start_B+Pos_B,end_B,K-Pos_B); else return findKth(A,B,start_A+Pos_A,end_A,startB,end_B,K-Pos_A) } }
要注意的几个点:
1.采用找两个数组第K个大小的值时,为了防止越界,需保证m<n。
2.有可能m<K,这里需要增加临界判断,以防止数组越界。
时间: 2024-10-26 21:20:39