【问题标题】:Java: Find the Kth largest element of an array, using 2 arraysJava:使用2个数组查找数组的第K大元素
【发布时间】:2019-03-12 10:01:52
【问题描述】:

这里是关于算法/解决方案的描述:

  • 输入:一个整数数组和一个数组索引
  • 输出:数组的第 K 个最大元素
  • 将前 K 个元素读入辅助数组(迄今为止发现的最大 K 个)
  • 对 K 元素数组进行排序
  • 然后:

     for each remaining element {
        if (if it is smaller than the smallest element of the aux. array) {
            throw it away
        } else { 
            remove the current smallest element of the auxiliary array
            place the element into the correct position in the auxiliary array
        }
     }
    
     then return the smallest (the Kth) element of the auxiliary array
    

我想出了以下解决方案:

public int findElement() throws IndexingError {
    int[] bigArray = getArray();
    int k = getIndex();
    if (k <= 0 || k > bigArray.length) {
        throw new IndexingError();
    }

    int[] smallArray = Arrays.copyOfRange(bigArray,0,k-1);
    Arrays.sort(smallArray);


    for (int i = k; i < bigArray.length; i++) {
        for (int ii = 1; ii < smallArray.length; ii++) {
            smallArray[ii-1] = smallArray[ii];
            if (bigArray[i] > smallArray[ii]) {
                smallArray[ii] = bigArray[i];
                System.out.println(smallArray[ii] + " " + smallArray[ii-1] + " " + bigArray[i]);
                break;

            }
        }

    }

    return smallArray[0];
}

例如:

代码应返回值:8,基于以下信息:

array = [2, 3, 8, 7, 1, 6, 5, 9, 4, 0]
k = 2

运行上面的代码每次都会产生不同的输出,如果你运行足够多次你会得到正确的答案?

有人可以识别/修复我的代码中的缺陷吗?

【问题讨论】:

  • 你把事情复杂化了,这不是一个非常困难的任务
  • 我同意VIPER,您可以简单地对数组进行排序并获取第K个元素。
  • 是的,我知道显而易见的解决方案是什么,但是我被要求专门这样做
  • 即使您被限制使用第二个数组,您也必须将k 元素以排序方式放入其中。因此,您可以使用任何排序算法,但对其稍作更改以将元素放置在第二个数组中并将其限制为 k 元素。例如,冒泡排序仅查找第一个 k 元素并将元素或元素索引放入第二个数组

标签: java arrays sorting for-loop int


【解决方案1】:

您需要解决以下问题:

  1. Arrays.copyOfRange(array, from, to) 方法中,to 索引是独占的。因此,您需要像 Arrays.copyOfRange(bigArray,0,k) 这样将第一个 k 元素复制到辅助数组。
  2. 循环遍历主数组中剩余的数组元素并更新辅助数组的逻辑是错误的。

例如,设辅助数组为:[4, 6],下一个主数组元素为2。根据您的逻辑,辅助数组将更新为[6, 6],因为您首先将索引1 处的元素复制到辅助数组中的索引0,然后检查新元素(来自主数组)是否大于辅助数组中索引1 处的元素。在这种情况下,新元素更小,所以只发生了复制,我们得到了损坏的辅助数组。

您只需要做的是,对于主数组中的每个新元素,检查它是否大于辅助数组中的第一个元素。如果是,那么这个新元素应该是辅助数组的一部分,并且应该放置在适当的位置。您可以使用冒泡排序技术找到合适的位置。

public int findElement() throws IndexingError {
    int[] bigArray = getArray();
    int k = getIndex();
    if (k <= 0 || k > bigArray.length) {
        throw new IndexingError();
    }

    int[] smallArray = Arrays.copyOfRange(bigArray,0,k);
    Arrays.sort(smallArray);


    for (int i = k; i < bigArray.length; i++) {
        if(bigArray[i] > smallArray[0]) {
            smallArray[0] = bigArray[i];
            int j = 0;
            while((j < k-1) && (smallArray[j] > smallArray[j+1])) {
                swap(smallArray[j], smallArray[j+1]);
                j++;
            }
        }

    }

    return smallArray[0];
}

【讨论】:

  • 我应该在哪里实现冒泡排序?在 while 循环内?
  • 我已经在上面的代码sn-p中实现了(类似于冒泡排序的技术)。
  • 嗯,好吧,所以我假设 swap() 将 smallArray[j+1] 中的值放入 smallArray[j]?
  • 交换值,将smallArray[j]的原值放入smallArray[j+1],将smallArray[j+1]的原值放入smallArray[j]
  • int temp = smallArray[j]; smallArray[j] = smallArray[j+1]; smallArray[j+1] = temp; 这是你可以使用的交换实现。
猜你喜欢
  • 2021-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多