1. 程式人生 > 其它 >leetcode 215. Kth Largest Element in an Array 陣列中的第K個最大元素

leetcode 215. Kth Largest Element in an Array 陣列中的第K個最大元素

一、題目大意

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 理解為什麼用快速選擇來解決這個問題是關鍵,重點是要理解快速排序