热题100_20230510
Posted xccx-0824
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了热题100_20230510相关的知识,希望对你有一定的参考价值。
215、数组中的第K个最大元素(堆排序,优先队列)
题目说明
给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。
解题思路1:优先队列
直接利用Java内置的PriorityQueue
进行排序处理,保证构造的优先队列是含有k个元素的且从队列尾部到头部从大到小排序(保证priorityQueue.peek()是队列中的最小值),反复用这个元素去和数组的其他元素进行比较判定是否需要替换新的元素进去。最终返回的priorityQueue.peek()即为第K大元素
在构造PriorityQueue
时要new PriorityQueue<Integer>(k, (a, b) -> a - b)
保证队头是最小的(小顶堆)
解题思路2:堆排序
其实就是优先队列的一个底层实现,不过我们仍然要学习堆排序,这很重要!
大根堆:每个节点的值都大于或者等于他的左右孩子节点的值。小根堆:每个结点的值都小于或等于其左孩子和右孩子结点的值
堆排序算法步骤:
- 把无序数组构建成为二叉堆(从上到下从左到右构建就好了)
- 循环删除堆顶元素,移到集合尾部,调节堆产生新的堆顶。
void HeapAdjust(int* arr, int start, int end)
int tmp = arr[start];
for (int i = 2 * start + 1; i <= end; i = i * 2 + 1)
if (i < end&& arr[i] < arr[i + 1])//有右孩子并且左孩子小于右孩子
i++;
//i一定是左右孩子的最大值
if (arr[i] > tmp)
arr[start] = arr[i];
start = i;
else
break;
arr[start] = tmp;
void HeapSort(int* arr, int len)
//第一次建立大根堆,从后往前依次调整
for(int i=(len-1-1)/2;i>=0;i--)
HeapAdjust(arr, i, len - 1);
//每次将根和待排序的最后一次交换,然后在调整
int tmp;
for (int i = 0; i < len - 1; i++)
tmp = arr[0];
arr[0] = arr[len - 1-i];
arr[len - 1 - i] = tmp;
HeapAdjust(arr, 0, len - 1-i- 1);
#yyds干货盘点# LeetCode 热题 HOT 100:子集
题目:
给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。
示例 1:
输入:nums = [1,2,3]
输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
示例 2:
输入:nums = [0]
输出:[[],[0]]
代码实现:
class Solution
List<Integer> t = new ArrayList<Integer>();
List<List<Integer>> ans = new ArrayList<List<Integer>>();
public List<List<Integer>> subsets(int[] nums)
dfs(0, nums);
return ans;
public void dfs(int cur, int[] nums)
if (cur == nums.length)
ans.add(new ArrayList<Integer>(t));
return;
t.add(nums[cur]);
dfs(cur + 1, nums);
t.remove(t.size() - 1);
dfs(cur + 1, nums);
以上是关于热题100_20230510的主要内容,如果未能解决你的问题,请参考以下文章
《 LeetCode 热题 HOT 100》——无重复字符的最长子串
Leecode02-两数相加——Leecode热题100道系列
Leecode02-两数相加——Leecode热题100道系列
Leecode22. 括号生成——Leecode大厂热题100道系列