leetcode 215. Kth Largest Element in an Array 陣列中的第K個最大元素
阿新 • • 發佈:2022-05-21
一、題目大意
https://leetcode.cn/problems/kth-largest-element-in-an-array
給定整數陣列 nums 和整數 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
提示:
- 1 <= k <= nums.length <= 104
- -104 <= nums[i] <= 104
二、解題思路
理解題意:
在一個未排序的陣列中,找到第k大的數字。輸入一個數組和一個目標k,輸出第k大的數字,題目黑夜一定有解。
解題思路:
快速選擇一般用於解決k-th Element問題,可以在O(n)時間複雜度,O(1)空間複雜度完成求解工作。快速選擇的實現和快速排序的實現類似,不過只需要找第k大的(pivort)即可,不需要對其進行左右排序。與快速排序一樣,快速選擇一般需要先打亂陣列,否則最壞情況下時間複雜度為O(n^2)。
解決思路:
陣列中第k個最大元素其實就是求陣列中第nums.length - k個最小元素,我們定義target = nums.length - k。
先找一箇中樞點(pivort),然後遍歷其他數字,小於pivort的排左邊,大於pivort的排右邊,中樞點是陣列中的第幾大的數字就確定了,如果pivort與target相等,直接返回pivort位置的數字,如果大於target,說明要求的數字在左邊部分,否則在右邊部分。剩下的就是遞迴了。
三、解題方法
3.1 Java實現
public class Solution { public int findKthLargest(int[] nums, int k) { int l = 0; int r = nums.length - 1; // 第k個大,就是第nums.length - k個小 int target = nums.length - k; while (l < r) { int mid = quickSelection(nums, l, r); if (mid == target) { return nums[mid]; } if (mid > target) { r = mid - 1; } else { l = mid + 1; } } return nums[l]; } /** * 快速選擇 */ private int quickSelection(int[] nums, int l, int r) { int i = l + 1; int j = r; while (true) { while (i < r && nums[i] <= nums[l]) { i++; } while (l < j && nums[j] >= nums[l]) { j--; } if (i >= j) { break; } swap(nums, i, j); } swap(nums, l, j); return j; } private void swap(int[] nums, int i, int j) { int tmp = nums[i]; nums[i] = nums[j]; nums[j] = tmp; } }
四、總結小記
- 2022/5/21 理解為什麼用快速選擇來解決這個問題是關鍵,重點是要理解快速排序