215. 数组中的第K个最大元素
快速选择
-
Arrays.sort()
调库快排
时间复杂度,空间复杂度
-
⭐
randPartition()
返回 pivot 的下标p
,代表pivot
为 第p
小的值。通过p
与k
比较来反复调用(分治)。
注:等号加在哪需要仔细考虑
时间复杂度,空间复杂度
注:
randPartition()
把数组分成了两部分。如果是快速排序,会在这里递归地对两部分进行快速排序。而在快速选择中,由于知道要找的第小的元素在哪部分中,我们不需要对两部分都做处理,这样就将平均时间复杂度下降到
。
-
Random rand = new Random(); int p = rand.nextInt(r - l + 1) + l; // 随机数生成
堆
-
创建一个大顶堆,将所有数组中的元素加入堆中,并保持堆的大小小于等于
。这样,堆中就保留了前
个最大的元素。这样,堆顶的元素就是正确答案。
PriorityQueue
实现原理为二叉小顶堆(可自定义Comparator)。poll()
为弹出小顶堆堆顶元素。
时间复杂度,空间复杂度
。
public int findKthLargest(int[] nums, int k) { PriorityQueue<Integer> pq = new PriorityQueue<>(); // 小顶堆 for (int val : nums) { pq.add(val); if (pq.size() > k) // 维护堆的大小为 K pq.poll(); } return pq.peek(); }
💣347. 前 K 个高频元素
自己没想出来
哈希表 + 桶排序(或建堆等排序算法)
将每个元素的出现频率存到哈希表。设置若干个桶,每个桶存储出现频率相同的数。桶的下标表示数出现的频率,即第 个桶中存储的数出现的频率为
。
从后向前遍历桶,最先得到的 个数就是出现频率最多的的
个数。
桶用 List<Integer>[]
表示。
- ⭐注意
List
数组的初始化。
List<Integer>[] tempList = new ArrayList[nums.length];
for (...) {
tempList[i] = new ArrayList<>();
}
- ⭐对于
List<List<Integer>>
类型,可以这样作插入(18题)
// result 为 List<List<Integer>> 类型, nums[i] 为 Integer
// Arrays.asList:数组转换为 List
// 8 个基本类型无法作为 asList 的参数,因此要用包装类型,如 Integer
result.add(new ArrayList<>(Arrays.asList(nums[i], nums[j], nums[l], nums[r])));
451. 根据字符出现频率排序
与上一题解法相同
哈希表 + 堆排序
桶排序时间复杂度优于堆排序。
- 字符串的处理对运行速度有较大影响。
String
通过+
运算符的拼接速度很慢(题目超时)。StringBuilder
中append()
比insert()
更快。
💣75. 颜色分类(荷兰国旗🇳🇱问题)
⭐三路快速排序 或 桶排序
// 三路快排思想,大于 1 的放右边,小于 1 的放左边,等于 1 的不动
while (one < two) {
if (nums[one] == 0) {
swap(nums, ++zero, one++);
}
else if (nums[one] == 2) {
swap(nums, --two, one);
}
else {
++one;
}
}