求给定两个排序好的数组中第k大的数
这个问题比求两个长度相等的排序数组的上中位数难度要高一点,难就难在不是求中位数了,但是我们要学会举一反三,可以尝试通过分析将求第k大的数转化为求中位数。将数组中不可能的数排除,在剩下可能的数中求中位数,这样就会产生3情况:
首先声明:两个数组,长度唱的为lenl,长度短的为lens。
1.k<lens;
2.lens<k<lenl
3,lenl<k<lenl+lens
4.k<1或k>lenl+lens,报错
代码实现:
public class UpMedian{ //求相同长度排序数组的中位数 public static int getUpMedian(int[] arr1,int start1,int end1,int[] arr2,int start2,int end2) { if(arr1==null || arr1.length<=0 || arr2==null || arr2.length<=0) { System.out.println("Array is valid"); return -1; } if(arr1.length!=arr2.length) { System.out.println("Array length is valid"); return -1; } int middle1 = 0; int middle2 =0; //用来区分数组长度为奇偶数 int offset = 0; while(start1 < end1) { middle1 = (start1+end1)>>1; middle2 = (start2+end2)>>1; offset = ((end1-start1+1)&1)^1; if(arr1[middle1] > arr2[middle2]) { end1=middle1; start2=middle2+offset; } else if(arr1[middle1] < arr2[middle2]) { start1 = middle1 +offset; end2 = middle2; } else { return arr1[middle1]; } } return Math.min(arr1[start1], arr2[start2]); } public static int fingKthNum(int[] arr1, int[] arr2, int k) { if(arr1==null || arr2==null || arr1.length<=0 || arr2.length<=0) { throw new RuntimeException("Array is valid"); } if(k<1 || k>(arr1.length+arr2.length)) { throw new RuntimeException("kth is valid"); } int res = 0; int[] longs = arr1.length>arr2.length ?arr1 : arr2; int[] shorts = arr1.length>arr2.length ?arr2 : arr1; int l = longs.length; int s = shorts.length; if(k<=s) { res = getUpMedian(arr1, 0, k-1, arr2, 0, k-1); } else if(k<=l) { if(longs[k-s-1]>=shorts[s-1]) { res = longs[k-s-1]; } else { res = getUpMedian(shorts, 0, s-1, longs, k-s, k-1); } } else if(k>l){ if(longs[k-s-1]>=shorts[s-1]) { res = longs[k-s-1]; } else if(shorts[k-l-1]>=longs[l-1]) { res = shorts[k-l-1]; } else { res = getUpMedian(shorts, k-l, s-1, longs, k-s, l-1); } } return res; } public static void main(String[] args) { int[] a1 = {1,2,5,7}; int[] a2 = {2,3,8,10}; System.out.println(fingKthNum(a1, a2, 4)); } }