欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

215. 数组中的第K个最大元素 快排思想+小根堆

程序员文章站 2024-02-14 23:59:28
...

215. 数组中的第K个最大元素

难度:中等
题目描述
215. 数组中的第K个最大元素 快排思想+小根堆
解题思路

1、排序

最简单最偷懒的当然是先排序,然后返回第n-k个元素,轻轻松松通过题数+1

public int findKthLargest(int[] nums, int k) {
        Arrays.sort(nums);
        int n = nums.length;
        return nums[n-k];

    }

215. 数组中的第K个最大元素 快排思想+小根堆

2、维护一个大小为k的堆

用优先队列来实现小根堆,堆顶是k个元素里最小的,k个数字之外,如果数字大于堆顶,就丢掉堆顶元素,加入新元素。

/*
		  * 215. 数组中的第K个最大元素
		  * 2020/6/29每日一题打卡  用优先队列实现小根堆(根比节点要小)
		  */
		 public int findKthLargest(int[] nums, int k) {
			 int n = nums.length;
			 PriorityQueue<Integer> minHeap = new PriorityQueue<>((a,b) -> a - b);
			 for(int i = 0; i < k; i++){
				 minHeap.offer(nums[i]);
			} 
			 for (int i = k; i < n; i++) {  //如果大于当前堆顶
				if(minHeap.peek() < nums[i]) {
					minHeap.poll();
					minHeap.offer(nums[i]);
				}
			}
			 return minHeap.peek();

		    }

215. 数组中的第K个最大元素 快排思想+小根堆

3、利用快排划分思想

快排的思想就是每次选取一个基准,以这个基准为划分,比这个数小的放左边,比这个数大的放右边。修改快排的划分方法,每次返回基准元素的下标,要找的数下标应该是n-k,所以如果返回的下标大于n-k,就继续划分右边;如果小于n-k,划分右边。
为了防止快排中存在的递归退化问题,每次不选择最左边的为基准,以中间元素为基准。(加了这个之后从16ms提高到了1ms)

 	public int findKthLargest(int[] nums, int k) {
			 return quickSelect(nums, 0, nums.length - 1, nums.length - k);
		    }
	 public int quickSelect(int[] a, int l, int r, int index) {
	        int q = partition(a, l, r);
	        if (q == index) {
	            return a[q];
	        } else {
	            return q < index ? quickSelect(a, q + 1, r, index) : quickSelect(a, l, q - 1, index);
	        }
	    }
		public int partition(int nums[],int low,int high) {
			if(low > high){
	            return -1;
	        }
               int p = (low + high) / 2;
               swap(nums,low,p);
			int i = low,j = high;
			int target = nums[low];
			while(i < j) {
				while(nums[j] >= target && i < j) {
					j--;
				}
				while(nums[i] <= target && i < j) {
					i++;
				}
				if(i < j)
					swap(nums, i, j);
			}
			if(i != low)
				swap(nums, i, low);	
			return i;
		}
		public void swap(int[] nums,int a,int b) {
			int temp = nums[a];
			nums[a] = nums[b];
			nums[b] = temp;
		}

215. 数组中的第K个最大元素 快排思想+小根堆

相关标签: 力扣刷题笔记