当前位置:网站首页>在两个有序数组中找到整体第K小的数可以做到O(log(Min(M,N)))

在两个有序数组中找到整体第K小的数可以做到O(log(Min(M,N)))

2022-06-24 21:19:00 N. LAWLIET

问题:
在两个有序数组中找到整体第K小的数可以做到O(log(Min(M,N)))

解题思路
解:分情况讨论
1)1<=k<=短数组长度
2)长数组长度<=k<=整体数组长度
3)短数组长度<=k<=长数组长度

代码

public class Code03_FindKthMinNumber {
    
	
	// 进阶问题 : 在两个都有序的数组中,找整体第K小的数
	// 可以做到O(log(Min(M,N)))
	public static int findKthNum(int[]arr1,int[] arr2,int kth) {
    
		int[] longs = arr1.length>arr2.length?arr1:arr2;
		int[] shorts = arr1.length<arr2.length?arr1:arr2;
		int s = shorts.length;
		int l = longs.length;
		if(kth<=s) {
    
			return getUpMedian(shorts, 0, kth-1, longs, 0, kth-1);
		}
		if(kth>=l) {
    
			if(shorts[kth-l-1]>longs[l-1]) {
    
				return shorts[kth-l-1];
			}
			if(longs[kth-s-1]>shorts[s-1]) {
    
				return longs[kth-s-1];
			}
			return getUpMedian(shorts, kth-l, s-1, longs, kth-s, l-1);
		}
		//s<kth<l
		else {
    
			if(longs[kth-s-1]>shorts[s-1]) {
    
				return longs[kth-s-1];
			}
			return getUpMedian(shorts, 0, s-1, longs,kth-s, l-1);
		}
		
	}
	
	//比较两个等长数组中位数
	public static int getUpMedian(int[]arr1,int s1,int e1,int[]arr2,int s2,int e2) {
    
		int mid1 = 0;
		int mid2 = 0;
		
		while(s1<e1) {
    
			mid1 = (s1+e1)/2;
			mid2 = (s2+e2)/2;
			if(arr1[mid1] == arr2[mid2]) {
    
				return arr1[mid1];
			}
			if(((e1-s1+1)&1) == 1) {
    //单数情况
				if(arr1[mid1]>arr2[mid2]) {
    
					if(arr2[mid2]>arr1[mid1-1]) {
    
						return arr2[mid2];
					}
					e1 = mid1-1;
					s2 = mid2 +1;
				}else {
    
					if(arr1[mid1]>=arr2[mid2-1]) {
    
						return arr1[mid1];
					}
					e2 = mid2 - 1;
					s1 = mid1 +1;
				}
			}else {
    
				if(arr1[mid1]>arr2[mid2]) {
    
					e1 = mid1;
					s2 = mid2+1; 
				}else {
    
					e2 = mid2;
					s1 = mid1 + 1;
				}
			}
		}
		return Math.min(arr1[mid1], arr2[mid2]);
	}

}

原网站

版权声明
本文为[N. LAWLIET]所创,转载请带上原文链接,感谢
https://blog.csdn.net/jiangzuofengqiao/article/details/125416601