【发布时间】:2017-03-04 11:57:19
【问题描述】:
给定两个大小为 M 和 N 的排序数组。我试图实现一个时间复杂度为 O(logM+logN) 的算法。该策略基本上是根据长度条件比较两个子数组中的中间索引元素。
// Test case 1
// Works for all position except when kth is 6
int[] num1 = {6,7,8,9,10,11,12};
int[] num2 = {1,2,3,4,5};
// Test case 2
// Always print the next smallest element
int[] num3 = {1,3,5,7,9};
int[] num4 = {2,4,6,8,10,12,14,16,18,20,22,24,30,40,50,56,77,35};
public static int findKth(int[] A, int p1, int r1, int[] B, int p2, int r2, int k){
if (p1 > r1) {
return B[p2+k-1];
} else if (p2 > r2) {
return A[p1+k-1];
}
int midA = p1 + (int)Math.floor((r1-p1)/2);// Middle element from subarray A
int midB = p2 + (int)Math.floor((r2-p2)/2);// Middle element from subarray B
/**
* Compare the sum of number of elements from left-subarray up to middle element.
*/
if ((midA-p1+midB-p2+2) < k) {
// We don't need to the left-subarray based on the comparisons between middle element
if (A[midA] > B[midB]) {
return findKth(A, p1, r1, B, midB+1, r2, k-(midB-p2+1)); //
} else {
return findKth(A, midA+1, r1, B, p2, r2, k-(midA-p1+1)); //
}
} else {
// We don't need to the right-subarray based on the comparisons between middle element.
if (A[midA] > B[midB]) {
return findKth(A, p1, midA-1, B, p2, r2, k);
} else {
return findKth(A, p1, r1, B, p2, midB-1, k);
}
}
}
我觉得我使用的策略应该是正确的。但是对于上面显示的两个测试用例,它会在某个特定的第 k 个值中打印错误的输出。所以我猜我的策略一定有问题。谁能简要描述一下这个实现的哪一部分是不正确的?谢谢!
【问题讨论】:
-
我猜你可以通过使用 minheap/maxheap 来解决这个问题,这是获取第 k 个最小元素的最佳方法之一
-
@Geeky 我知道还有很多其他方法可以解决这个问题。但是你能发现我在这个算法上做错了什么吗?
标签: arrays algorithm time-complexity