Java 8:如何有效地找到第k个最小的

时间:2017-02-08 13:09:27

标签: java java-8 java-stream comparator

在java 8中,如何有效地找到Kth最小? Kth最小的是

http://www.geeksforgeeks.org/kth-smallestlargest-element-unsorted-array/

我在下面尝试过。如果有一个更有效的解决方案,它提供了Java-8的证券,例如在空数组等情况下访问索引之前我不应该检查大小。我相信我自己的解决方案是安全的空数组。

我的Java-8方法的可证明的时间复杂度比较和更好的Java-8方法如果存在,将会受到赞赏。谢谢。

package lab.rat.jerry.kthsmallest;

import static java.util.stream.Collectors.toList;

import java.util.Arrays;
import java.util.List;

public class KthSmallest {

    // Inputs
    static int k = 3;

    static Integer[] myIntArray = {2, 3, 1, 4, -2, 0, -3, 0, -1, 5 };

    public static void main(String[] args) {

        List<Integer> list = Arrays.asList(myIntArray);

        System.out.println(list
            .stream()
            .sorted()
            .distinct()
            .limit(k)
            .skip(k-1)
            .collect(toList())
            );
    }
}

3 个答案:

答案 0 :(得分:2)

您可以在Java中使用简单的数据结构PrioretyQueue。您可以快速获取和删除最大或最小元素:

public static int kthLargestElement(int[] nums, int k) {

    PriorityQueue<Integer> queue = new PriorityQueue<>();
    for (int i = 0; i < nums.length ; i++) {
        queue.add(nums[i]);
    }
    while (k > 1){
        queue.poll();
        k-=1;
    }
    return queue.poll();
}

答案 1 :(得分:0)

你可以试试这个:

package lab.rat.jerry.kthsmallest;

import java.util.Arrays;
import java.util.List;

public class KthSmallest {

       // Inputs
      static int k = 3;

      static Integer[] myIntArray = {2, 3, 1, 4, -2, 0, -3, 0, -1, 5 };

      public static void main(String[] args) {

         List<Integer> list = Arrays.asList(myIntArray);

         int smallest = list.stream()
                            .mapToInt(Integer::intValue)
                            .sorted()
                            .limit(k)
                            .skip(k-1)
                            .findFist()
                            .getAsInt();
         System.out.println(smallest);
     }
}

通过使用此方法,您可以避免NullPointerException。因为findFist()将返回可选项。

希望有所帮助:)

答案 2 :(得分:0)

我不知道这有多有效,但是在以下情况下会考虑到

  1. 该数组包含重复值。
  2. k大于最终列表。
      int k = 4;
      int[] numbs = { 1, 2, 3, 3, 3, 3, 3, 3,10,11,12
      };

      int smallest =
            Arrays.stream(numbs).distinct().sorted().skip(k - 1).limit(
                  1).findFirst().orElse(Integer.MIN_VALUE);

      System.out.println(smallest);
  1. 这会将数组转换为流。
  2. 删除重复项
  3. 对剩下的内容进行排序。
  4. 跳过前k-1个值。
  5. 将列表的其余部分限制为一个
  6. 退回它。

如果k太大,则返回最小int值。