力扣215(找出数组中第k大的值)

 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

class Solution {
    public int findKthLargest(int[] nums, int k) {
        //利用堆解决:
        //1.向小顶堆放入前k个元素
        //2.对于剩余的元素
        //若小于或等于堆顶元素,略过,否则替换堆顶元素
        //3.小顶堆始终保留的是到目前为止前k大的元素
        //4.循环结束时,堆顶元素就是结果
        maxHeap heap = new maxHeap(k);
        for(int i = 0;i < k;i++){
            heap.offer(nums[i]);
        }
        for(int i = k; i < nums.length;i++){
            if(nums[i] > heap.peek()){
               heap.replace(nums[i]);
            }
        }
        return heap.peek();
    }
}

class maxHeap{
    int[] array;
    int size;

    public maxHeap(int k) {
		this.array = new int[k];
	}

    //向堆的尾部添加元素
    public void offer(int offered) {
        up(offered);
        size++;
    }
    // 替换堆顶元素
	public void replace(int replaced) {
        array[0] = replaced;
        down(0);
    }
    // 获取堆顶元素
	public int peek() {
		return array[0];
	}
    //元素上浮
    public void up(int offered) {//关键是找到要擦入的位置
        int child = size;
        while(child > 0){
            int parent = (child - 1) / 2;// 得到要插入元素的父元素
            if(array[parent] > offered){
                array[child] = array[parent];//将父元素的值给子元素
            }else{
                break;
            }
            child = parent;//继续向上找
        }
        array[child] = offered;//找到
    }

    // 将parent索引处的元素下潜 
	public void down(int parent) {
		int left = parent * 2 + 1;
		int right = left + 1;
		int min = parent;// 用于记录左右孩子哪一个孩子的数值更大,记下他的索引
		if (left < size && array[left] < array[min]) {// left可能会越界
			min = left;
		}
		if (right < size && array[right] < array[min]) {
			min = right;
		}
		if (min != parent) {// 找到了最大的孩子,交换他们的值
			swap(min, parent);
			// 递归
			down(min);// 将最大值继续向下潜
		}
	}
    // 交换两个索引处的值
	private void swap(int i, int j) {
		int t = array[i];
		array[i] = array[j];
		array[j] = t;
	}

}

你可能感兴趣的:(leetcode,算法,java)