【问题标题】:Find K Smallest Elements in an Array查找数组中的 K 个最小元素
【发布时间】:2021-01-13 00:08:00
【问题描述】:

我想在一个数组中找到 K 个最小的元素,并且我基本上能够将我的数组排序为一个最小堆结构,但我仍然得到错误的输出。

这是我的输入:

arr = [9,4,7,1,-2,6,5]
k = 3

这是代码:

public static int[] findKSmallest(int[] arr, int k) {
    int[] result = new int[k];
    int heapSize = arr.length;
    // Write - Your - Code  

    for (int i = (heapSize - 1) / 2; i >= 0; i--) {
        minHeap(arr, i, heapSize);
    }

    for (int j = 0; j < k; j++) {
        result[j] = arr[j];
    }
    return result;
}
public static void minHeap(int[] arr, int index, int heapSize) {
    int smallest = index;
    while (smallest < heapSize / 2) {
        int left = (2 * index) + 1; // 1 more than half the index
        int right = (2 * index) + 2; // 2 more than half the index 

        if (left < heapSize && arr[left] < arr[index]) {
            smallest = left;
        }

        if (right < heapSize && arr[right] < arr[smallest]) {
            smallest = right;
        }

        if (smallest != index) {
            int temp = arr[index];
            arr[index] = arr[smallest];
            arr[smallest] = temp;
            index = smallest;
        } else {
            break;
        }
    }
}

这是我的预期输出:

[-2,1,4]

虽然我的输出是:

[-2,1,5]

我想知道我哪里出错了。

【问题讨论】:

    标签: java arrays min


    【解决方案1】:

    构建 minHeap 后,您必须提取元素并适当调整树。您只需按索引从数组中获取元素,这不是堆的工作方式。

    我稍微修改了您的minHeap() 方法以使用recursion,您应该检查arr[smallest] &lt; arr[left] 而不是相反的方式。

    public static int[] findKSmallest(int[] arr, int k) {
        int[] result = new int[k];
        int heapSize = arr.length;
        // Write - Your - Code
    
        for (int i = (heapSize - 1) / 2; i >= 0; i--) {
            minHeap(arr, heapSize, i);
        }
    
        // extract elements from heap
        for (int i = heapSize - 1; i > 0; i--) {
            int temp = arr[0];
            arr[0] = arr[i];
            arr[i] = temp;
            minHeap(arr, 0, i);
        }
    
        for (int j = 0; j < k; j++) {
            result[j] = arr[j];
        }
        return result;
    }
    
    public static void minHeap(int[] arr, int index, int heapSize) {
        int smallest = index;
        int left = (2 * index) + 1; // 1 more than half the index
        int right = (2 * index) + 2; // 2 more than half the index
        if (left < heapSize && arr[smallest] < arr[left]) {
            smallest = left;
        }
        if (right < heapSize && arr[smallest] < arr[right]) {
            smallest = right;
        }
        if (smallest != index) {
            int temp = arr[index];
            arr[index] = arr[smallest];
            arr[smallest] = temp;
            minHeap(arr, smallest, heapSize);
        }
    }
    

    希望这会有所帮助。不出所料,结果是:

    [-2, 1, 4]
    

    【讨论】:

      【解决方案2】:

      从 Java 8 开始我们可以对流进行排序

      替代代码:

      Arrays.stream(arr).sorted().boxed().collect(Collectors.toList()).subList(0, k);
      

      地点:

      int[] arr = {9,4,7,1,-2,6,5};
      int k = 3; // toIndex
      

      上下文和测试平台中的替代代码:

      public static void main(String[] args) {
          int[] arr = {9, 4, 7, 1, -2, 6, 5};
          int k = 3; // toIndex
      
          List<Integer> listResult = Arrays.stream(arr)
                  .sorted().boxed().collect(Collectors.toList()).subList(0, k);
          // print out list result
          System.out.println("Output of list result: " + listResult);
      
      
          int[] arrayResult = listResult.stream().mapToInt(i -> i).toArray();
          // print out array result
          List<String> arrayResultAsString = Arrays.stream(arrayResult)
                  .boxed().map(i -> String.valueOf(i)).collect(Collectors.toList());
          System.out.println("Output of array result: " + arrayResultAsString);
      }
      

      输出:

      Output of list result: [-2, 1, 4]
      Output of array result: [-2, 1, 4]
      

      【讨论】:

        【解决方案3】:

        你可以使用Arrays.stream​(int[])方法:

        int[] arr = {9, 4, 7, 1, -2, 6, 5};
        int k = 3;
        
        int[] minHeap = Arrays.stream(arr).sorted().limit(k).toArray();
        
        System.out.println(Arrays.toString(minHeap)); // [-2, 1, 4]
        

        【讨论】:

          【解决方案4】:

          如果 K 相对于数组大小相对较小,我的建议是使用选择排序,因此它可能是一种设计模式策略 - 取决于 K 与数组大小的关系,例如两个过程:小 K 的选择排序和快速排序巨大的 K。与其玩设计模式,不如使用简单的 if 语句,例如选择

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-12-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-12-24
            • 2012-10-22
            相关资源
            最近更新 更多