[Leedcode][第215题][JAVA][数组中的第K个最大元素][快排][优先队列]

【问题描述】[中等]

在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。示例 1:输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
示例 2:输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4
说明:你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度。

【解答思路】

1. 暴力解法(快排)

在这里插入图片描述
时间复杂度:O(NlogN) 空间复杂度:O(1)

import java.util.Arrays;public class Solution {public int findKthLargest(int[] nums, int k) {int len = nums.length;Arrays.sort(nums);return nums[len - k];}
}
2. 借助 partition 操作定位到最终排定以后索引为 len - k 的那个元素(特别注意:随机化切分元素)

在这里插入图片描述
时间复杂度:O(N) 空间复杂度:O(1)
在这里插入图片描述

public class Solution {public int findKthLargest(int[] nums, int k) {int len = nums.length;int left = 0;int right = len - 1;// 转换一下,第 k 大元素的索引是 len - kint target = len - k;while (true) {int index = partition(nums, left, right);if (index == target) {return nums[index];} else if (index < target) {left = index + 1;} else {right = index - 1;}}}/*** 在数组 nums 的子区间 [left, right] 执行 partition 操作,返回 nums[left] 排序以后应该在的位置* 在遍历过程中保持循环不变量的语义* 1、[left + 1, j] < nums[left]* 2、(j, i] >= nums[left]** @param nums* @param left* @param right* @return*/public int partition(int[] nums, int left, int right) {int pivot = nums[left];int j = left;for (int i = left + 1; i <= right; i++) {if (nums[i] < pivot) {// 小于 pivot 的元素都被交换到前面j++;swap(nums, j, i);}}// 在之前遍历的过程中,满足 [left + 1, j] < pivot,并且 (j, i] >= pivotswap(nums, j, left);// 交换以后 [left, j - 1] < pivot, nums[j] = pivot, [j + 1, right] >= pivotreturn j;}private void swap(int[] nums, int index1, int index2) {int temp = nums[index1];nums[index1] = nums[index2];nums[index2] = temp;}
}

在这里插入图片描述

import java.util.Random;public class Solution {private static Random random = new Random(System.currentTimeMillis());public int findKthLargest(int[] nums, int k) {int len = nums.length;int target = len - k;int left = 0;int right = len - 1;while (true) {int index = partition(nums, left, right);if (index < target) {left = index + 1;} else if (index > target) {right = index - 1;} else {return nums[index];}}}// 在区间 [left, right] 这个区间执行 partition 操作private int partition(int[] nums, int left, int right) {// 在区间随机选择一个元素作为标定点if (right > left) {int randomIndex = left + 1 + random.nextInt(right - left);swap(nums, left, randomIndex);}int pivot = nums[left];int j = left;for (int i = left + 1; i <= right; i++) {if (nums[i] < pivot) {j++;swap(nums, j, i);}}swap(nums, left, j);return j;}private void swap(int[] nums, int index1, int index2) {int temp = nums[index1];nums[index1] = nums[index2];nums[index2] = temp;}
} 

在这里插入图片描述

import java.util.Random;public class Solution {private static Random random = new Random(System.currentTimeMillis());public int findKthLargest(int[] nums, int k) {int len = nums.length;int left = 0;int right = len - 1;// 转换一下,第 k 大元素的索引是 len - kint target = len - k;while (true) {int index = partition(nums, left, right);if (index == target) {return nums[index];} else if (index < target) {left = index + 1;} else {right = index - 1;}}}public int partition(int[] nums, int left, int right) {// 在区间随机选择一个元素作为标定点if (right > left) {int randomIndex = left + 1 + random.nextInt(right - left);swap(nums, left, randomIndex);}int pivot = nums[left];// 将等于 pivot 的元素分散到两边// [left, lt) <= pivot// (rt, right] >= pivotint lt = left + 1;int rt = right;while (true) {while (lt <= rt && nums[lt] < pivot) {lt++;}while (lt <= rt && nums[rt] > pivot) {rt--;}if (lt > rt) {break;}swap(nums, lt, rt);lt++;rt--;}swap(nums, left, rt);return rt;}private void swap(int[] nums, int index1, int index2) {int temp = nums[index1];nums[index1] = nums[index2];nums[index2] = temp;}
}
3. 优先队列

在这里插入图片描述

import java.util.PriorityQueue;public class Solution {public int findKthLargest(int[] nums, int k) {int len = nums.length;// 使用一个含有 len 个元素的最小堆,默认是最小堆,可以不写 lambda 表达式:(a, b) -> a - bPriorityQueue<Integer> minHeap = new PriorityQueue<>(len, (a, b) -> a - b);for (int i = 0; i < len; i++) {minHeap.add(nums[i]);}for (int i = 0; i < len - k; i++) {minHeap.poll();}return minHeap.peek();}
}
import java.util.PriorityQueue;public class Solution {public int findKthLargest(int[] nums, int k) {int len = nums.length;// 使用一个含有 len 个元素的最大堆,lambda 表达式应写成:(a, b) -> b - aPriorityQueue<Integer> maxHeap = new PriorityQueue<>(len, (a, b) -> b - a);for (int i = 0; i < len; i++) {maxHeap.add(nums[i]);}for (int i = 0; i < k - 1; i++) {maxHeap.poll();}return maxHeap.peek();}
}

在这里插入图片描述

import java.util.PriorityQueue;public class Solution {public int findKthLargest(int[] nums, int k) {int len = nums.length;// 使用一个含有 k 个元素的最小堆PriorityQueue<Integer> minHeap = new PriorityQueue<>(k, (a, b) -> a - b);for (int i = 0; i < k; i++) {minHeap.add(nums[i]);}for (int i = k; i < len; i++) {// 看一眼,不拿出,因为有可能没有必要替换Integer topEle = minHeap.peek();// 只要当前遍历的元素比堆顶元素大,堆顶弹出,遍历的元素进去if (nums[i] > topEle) {minHeap.poll();minHeap.add(nums[i]);}}return minHeap.peek();}
}

在这里插入图片描述

import java.util.PriorityQueue;public class Solution {public int findKthLargest(int[] nums, int k) {int len = nums.length;// 最小堆PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(k + 1, (a, b) -> (a - b));for (int i = 0; i < k; i++) {priorityQueue.add(nums[i]);}for (int i = k; i < len; i++) {priorityQueue.add(nums[i]);priorityQueue.poll();}return priorityQueue.peek();}
}

在这里插入图片描述

import java.util.PriorityQueue;public class Solution {// 根据 k 的不同,选最大堆和最小堆,目的是让堆中的元素更小// 思路 1:k 要是更靠近 0 的话,此时 k 是一个较大的数,用最大堆// 例如在一个有 6 个元素的数组里找第 5 大的元素// 思路 2:k 要是更靠近 len 的话,用最小堆// 所以分界点就是 k = len - kpublic int findKthLargest(int[] nums, int k) {int len = nums.length;if (k <= len - k) {// System.out.println("使用最小堆");// 特例:k = 1,用容量为 k 的最小堆// 使用一个含有 k 个元素的最小堆PriorityQueue<Integer> minHeap = new PriorityQueue<>(k, (a, b) -> a - b);for (int i = 0; i < k; i++) {minHeap.add(nums[i]);}for (int i = k; i < len; i++) {// 看一眼,不拿出,因为有可能没有必要替换Integer topEle = minHeap.peek();// 只要当前遍历的元素比堆顶元素大,堆顶弹出,遍历的元素进去if (nums[i] > topEle) {minHeap.poll();minHeap.add(nums[i]);}}return minHeap.peek();} else {// System.out.println("使用最大堆");assert k > len - k;// 特例:k = 100,用容量为 len - k + 1 的最大堆int capacity = len - k + 1;PriorityQueue<Integer> maxHeap = new PriorityQueue<>(capacity, (a, b) -> b - a);for (int i = 0; i < capacity; i++) {maxHeap.add(nums[i]);}for (int i = capacity; i < len; i++) {// 看一眼,不拿出,因为有可能没有必要替换Integer topEle = maxHeap.peek();// 只要当前遍历的元素比堆顶元素大,堆顶弹出,遍历的元素进去if (nums[i] < topEle) {maxHeap.poll();maxHeap.add(nums[i]);}}return maxHeap.peek();}}
}

【总结】

1.快排核心思想 找partition 随机化可避免极端情况
2.优先队列的使用 最大最小堆
//大堆
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(capacity, (a, b) -> b - a);
//小堆PriorityQueue<Integer> minHeap = new PriorityQueue<>(k, (a, b) -> a - b);

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.assert 调试使用 程序或软件正式发布后需要关闭

在这里插入图片描述
在这里插入图片描述

转载链接:https://leetcode-cn.com/problems/kth-largest-element-in-an-array/solution/partitionfen-er-zhi-zhi-you-xian-dui-lie-java-dai-/

参考链接:https://blog.csdn.net/jeikerxiao/article/details/82262487
参考链接:https://www.cnblogs.com/wei-jing/p/10806236.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/425404.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CF#420 B. Okabe and Banana Trees 思维|暴力|几何

Okabe needs bananas for one of his experiments for some strange reason. So he decides to go to the forest and cut banana trees. Consider the point (x, y) in the 2D plane such thatx andy are integers and0 ≤ x, y. There is a tree in such a point, and i…

30jquery-qrcode生成二维码

链接&#xff1a;https://pan.baidu.com/s/1KHzX_jFFBaw4QBKBR8UrgA 提取码&#xff1a;qmdo 复制这段内容后打开百度网盘手机App&#xff0c;操作更方便哦 如上所示&#xff0c;建立一个web程序 <% page language"java" contentType"text/html; charsetUTF-…

Linux系统添加永久静态路由的方法

一、使用route命令添加 使用route 命令添加的路由&#xff0c;机器重启或者网卡重启后路由就失效了&#xff0c;方法&#xff1a;A、添加到主机的路由# route add –host 192.168.1.10 dev eth0# route add –host 192.168.1.10 gw 192.168.1.1B、添加到网络的路由# route add …

[剑指offer]面试题第[50]题[JAVA][第一个只出现一次的字符][哈希表][HashMap]

【问题描述】[简单] 在字符串 s 中找出第一个只出现一次的字符。如果没有&#xff0c;返回一个单空格。 s 只包含小写字母。示例:s "abaccdeff" 返回 "b"s "" 返回 " "【解答思路】 1. 哈希表 时间复杂度&#xff1a;O(N) 空间复…

31.javaweb简介

1 2 3 4 5 6 7javaweb程序简介

K-Dominant Character CodeForces - 888C 思维 构造

题意 让我们在这个字符串中找一定k长度的字串中都至少含有一个相同的字符 让求这个字串的最小长度 分析 也就是说当我们最终确定了 字串的最小长度后 每个以此长度的字串都至少含有一个相同字符 那么当我们找这个长度的时候 也就是说 每个k长度的字串中都至少出现一个相同的…

display:table的用法

目前&#xff0c;在大多数开发环境中&#xff0c;已经基本不用table元素来做网页布局了&#xff0c;取而代之的是divcss&#xff0c;那么为什么不用table系表格元素呢&#xff1f; 1、用DIVCSS编写出来的文件k数比用table写出来的要小&#xff0c;不信你在页面中放1000个table和…

[剑指offer]面试题第[38]题[JAVA][字符串的排列][回溯法]

【问题描述】[中等] 输入一个字符串&#xff0c;打印出该字符串中字符的所有排列。 你可以以任意顺序返回这个字符串数组&#xff0c;但里面不能有重复元素。示例: 输入&#xff1a;s "abc" 输出&#xff1a;["abc","acb","bac",&qu…

32tomcat的目录结构

<% page language"java" contentType"text/html; charsetUTF-8"pageEncoding"UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>歌谣</title> </head> <bod…

Codeforces Round #413 C-Fountains 树状数组

题意 本题给我们给我们两种货币初始金额 每种货币分别对应能买不同种类的喷泉 每个喷泉有花费和价值 问我们如果单纯建造两个喷泉在限定金额内的最大值 分析 考虑一下 发现有三种情况 &#xff11; 两个喷泉从coin中里建造 &#xff12; 两个喷泉从diamond中建造 &…

[剑指offer]面试题第[52]题[Leedcode][第160题][JAVA][相交链表][双指针]

【问题描述】[简单] 【解答思路】 1. 双指针法 时间复杂度&#xff1a;O(N^2) 空间复杂度&#xff1a;O(1) public ListNode getIntersectionNode(ListNode headA, ListNode headB) {if (headA null || headB null) return null;ListNode pA headA, pB headB;while (pA !…

redis 分布式锁实现

<?php /*** 实现Redis分布锁*/$key test; //要更新信息的缓存KEY $lockKey lock:.$key; //设置锁KEY $lockExpire 10; //设置锁的有效期为10秒 //获取缓存信息 $result $redis->get($key); //判断缓存中是否有数据 if(empty($result)) { $status TRUE…

33tomcat目录结构

1创建一个myhome文件 2创建一个index.jsp文件 <% page language"java" contentType"text/html; charsetUTF-8"pageEncoding"UTF-8"%><!DOCTYPE html><html><head><meta charset"utf-8"><title>歌…

CodeForces 799B (B) T-shirt buying

分析 本题实质上就是对数据处理一下就可以了 就是数据结构实现题 我们要求对应索引下按照某种排序规则的线性表时 取最优时 可以用堆 每次拿出一个元素 堆内元素调整顺序 然后用三个堆 就可以表示三张表 每次我们得到顾客的一个喜欢颜色 就可以利用这个颜色去查堆 找到就输出…

复合数据类型,英文词频统计

作业要求&#xff1a;https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/2696 1.列表&#xff0c;元组&#xff0c;字典&#xff0c;集合分别如何增删改查及遍历。 列表的增删改查list1 list(this is a list)#增加list1.append(!) #末尾增加元素list1.insert(2,this i…

34tomcat设置默认页面

如何让hah.jsp成为欢迎界面&#xff1f; 在web-inf文件夹中配置项目部署文件web.xml。 添加标签 <welcome-file-list> <welcome-file>/hah.jsp</welcome-file> <welcome-file-list> 改变web.xml文件首页&#xff0c;报 将文件变成hah.jsp 默认页就设置…

[Leetcode][第718题][JAVA][最长重复子数组][动态规划][滑动窗口][暴力]

【问题描述】[中等] 给两个整数数组 A 和 B &#xff0c;返回两个数组中公共的、长度最长的子数组的长度。示例 1:输入: A: [1,2,3,2,1] B: [3,2,1,4,7] 输出: 3 解释: 长度最长的公共子数组是 [3, 2, 1]。 说明:1 < len(A), len(B) < 1000 0 < A[i], B[i] < 100…

CodeForces 841C (C) Leha and Function 贪心

题意 定义F(n,k)表示&#xff11;&#xff0d;&#xff4e;的数列中以&#xff4b;为子集总个数的最小值 现有&#xff21;&#xff0c;&#xff22;数组 让我们重新排列&#xff21; 使得sigma[1 len]F(ai,bi)的数学期望最大 分析 题目看上去有点绕 但从期望上分析下其…

技术方法论

1、pom.xml配置新版本的jar包&#xff0c;如果引用不到可以先删除本地仓库的jar包&#xff0c;从私服重新下载新版本 转载于:https://www.cnblogs.com/luao/p/10535817.html