理解为什么Java选择等级返回max()作为最终结果

时间:2015-11-01 17:08:09

标签: java algorithm

我正在研究以下问题的解决方案:

  

描述一种算法,在一个中找到最小的一百万个数字   十亿数字。假设计算机存储器可以容纳所有计算机存储器   十亿数字。

这本书提供了一个选择等级解决方案,但我很难理解它的一些部分:

public static int partition(int[] array, int left, int right, int pivot) {
    while (true) {
        while (left <= right && array[left] <= pivot) {
            left++;
        }

        while (left <= right && array[right] > pivot) {
            right--;
        }

        if (left > right) {
            return left - 1;
        } 
        swap(array, left, right);
    }
}

public static int rank(int[] array, int left, int right, int rank) {
    int pivot = array[randomIntInRange(left, right)];
    int leftEnd = partition(array, left, right, pivot); // returns end of left partition
    int leftSize = leftEnd - left + 1;
    if (leftSize == rank + 1) {
        return max(array, left, leftEnd);
    } else if (rank < leftSize) {
        return rank(array, left, leftEnd, rank);
    } else {
        return rank(array, leftEnd + 1, right, rank - leftSize);
    }
}  

我理解其中的大部分内容,但我不理解以上两行:

if (leftSize == rank + 1) {
            return max(array, left, leftEnd);

1。为什么我们返回三个变量的最大值?

2。我们不应该只是返回array[left:leftEnd]或那种性质的东西吗?

2 个答案:

答案 0 :(得分:1)

恭喜您通过仔细研究一本书来学习。这是一项似乎越来越少的关键技能。

如果rank的返回值的定义是&#34,那么通常会有一般意义:正好有一百万个数字小于或等于rank。&#34; max的定义类似于:

int t = array[left];
for (int i = left + 1; i <= leftEnd; i++) 
  t = Math.max(t, array[i]);
return t;

返回最大值超出了问题陈述,有点奇怪。将元素分区以使最大百万位于顶部会更好,更简单:array[0] through array[999999]。然后只有在实际需要的时候找到最大值

请注意,因为rank是尾递归的,所以我认为相同代码的简单迭代版本会更清晰。

我也不相信这段代码是正确的。检查中的leftSize == rankleftSize == rank + 1更有意义。但如果没有更多的定义和调用代码,很难肯定。

答案 1 :(得分:0)

Cracking the Coding Interview 6th Edition p中使用相同的等级函数。 569 (除了该行:if (leftSize == rank + 1) {被修改为rank - 1)。

提供了最大功能,如下所示:

/* Get largest element in array between left and right indices */
int max(int[] array, int left, int right)
{
    int max = Integer.MIN_VALUE;
    for(int i = left; i <= right; i++) 
    {
        max = Math.max(array[i], max);
    }
    return max;
}

至于解释:rank(array, rank)返回将在排序数组的第i个位置的元素。

leftEnd是枢轴的位置。如果在pivot元素之前有rank - 1个元素,则包含所述pivot的rank个元素。

我相信枢轴始终是最大元素,因此max(array, left, leftEnd);的调用可以替换为return pivot;