topic link
Niuke online oj question - the smallest number of K
topic description
Given an array of length n that may have duplicate values, find the smallest k numbers that do not remove duplicates. For example, the array elements are 8 numbers 4, 5, 1, 6, 2, 7, 3, 8, and the smallest 4 numbers are 1, 2, 3, 4 (in any order).
Data range: 0≤k, n≤10000, the maximum of each number in the array 0≤val≤1000
Requirements: space complexity O(n), time complexity O(nlogk)
Topic example
Example 1
Input:
[4,5,1,6,2,7,3,8],4
Return value:
[1,2,3,4]
Explanation:
It is enough to return the smallest 4 numbers, and it is also possible to return [1,3,2,4]
Example 2
Input:
[1],0
return value:
[]
Example 3
Input:
[0,1,2,1,2],3
Return value:
[0,1,1]
problem solving ideas
This question is a typical topK problem, you can directly use any kind of sorting, arrange the elements in the array in ascending order, and then directly return the first k numbers
A better solution is to construct a large root heap with k elements, first insert the first k elements of the array into the heap, and then continue to traverse the elements in the array from left to right
The characteristics of the big root heap are: the top element of the heap is larger than all the elements below
When the traversed element i is larger than the element peek at the top of the large root heap, it means that i is definitely not an element among the smallest k numbers, and continue to traverse the next position
When the traversed element i is smaller than the element peek at the top of the big root heap, it means that peek is definitely not an element in the smallest k number, pop the top element of the big root heap, and insert i into the big root heap
Traverse the entire array sequence, and finally all the elements in the big root heap are the smallest k numbers
For example:
first insert the first four elements into the big root heap.
The currently traversed element is 2, which is smaller than the top element 6 of the big root heap. Pop 6 out and put 2 into the big root heap. The
currently traversed element of i++ is 7, which is smaller than the top element of the big root heap. The element at the top of the heap is 5, which is definitely not among the smallest k numbers. Continue traversing. The
currently traversed element is 3, which is smaller than the top element 5 of the big root heap. Pop 5 out of the big root heap, and insert 3 into the big root heap
. The element is 8, which is larger than the top element 4 of the big root heap. It must not be among the smallest k numbers. After the traversal is over, all the elements stored in the current big root heap are the smallest k number.
full code
import java.util.*;
public class Solution {
public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
ArrayList<Integer> result = new ArrayList<>();
if(input == null || k <= 0 || k > input.length){
return result;
}
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(k, Collections.reverseOrder());
for (int i = 0; i < input.length; i++){
if(i < k){
priorityQueue.offer(input[i]);
} else {
if(input[i] < priorityQueue.peek()){
priorityQueue.poll();
priorityQueue.offer(input[i]);
}
}
}
for (int i = 0; i < k; i++){
result.add(priorityQueue.poll());
}
return result;
}
}