剑指offerNo29. 最小的K个数(Java)

题目描述:

输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。

思路:

方法一:

先进行排序,再返回前K个数。复杂度是O(nlogn)

方法二:

维护一个大根堆,我们用PriorityQueue实现大顶堆,PriorityQueue默认是一个小顶堆,然而可以通过传入自定义的Comparator函数来实现大顶堆。

  • 遍历数组,当堆中元素个数小于k时,直接添加到堆里。
  • 当堆中元素个数大于k时,开始比较遍历的当前元素是否大于此时堆的堆顶元素,如果大于,则继续遍历数组中的下一个数,如果小于,则删除堆顶元素,并将当前数添加到堆中。
  • 当整个数组遍历完之后,则此时维护的堆就是我们需要的最小的K个数。

代码:

package offer;

import org.omg.PortableInterceptor.INACTIVE;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.PriorityQueue;

public class TestNo29 {
    public static void main(String[] args) {
        int[] a = {4,5,1,6,2,7,3,8};
        System.out.println(new TestNo29().GetLeastNumbers_Solution(a,4));

    }
    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
        ArrayList list = new ArrayList();
        if(k >input.length || k==0){
            return list;
        }
        //以下是使用PriorityQueue的Comparator维护一个大根堆
        PriorityQueue<Integer> queue = new PriorityQueue<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2-o1;
            }
        });
        //进行遍历
        for(int i= 0;i<input.length;i++){
            //如果堆中数的个数小于K,则直接加入堆中
            if(i<k){
                queue.offer(input[i]);
            }else if(queue.peek() > input[i]){
                //如果堆顶元素大于当前遍历元素,则将堆顶元素删除,并将当前遍历的元素加入堆
                queue.poll();
                queue.offer(input[i]);
            }
        }
        //遍历完数组的数之后,堆里面保留的数就是当前最小的k个数,用list返回
        for(int i = 0;i<k ; i++){
            list.add(queue.poll());
        }
        return list;




    }
}
发布了65 篇原创文章 · 获赞 13 · 访问量 4446

猜你喜欢

转载自blog.csdn.net/qq_40664693/article/details/104434466
今日推荐