• 力扣215.数组中的第K个最大元素


    215. 数组中的第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 ≤ 数组的长度。

    思路一:排序后取值

    复杂度分析:

    时间复杂度:排序时间为O(nlogn),所以时间为O(nlogn)

    空间复杂度:O(1)

    思路二:利用堆

    维持一个大小为K的最小堆,堆顶的元素始终是当前所有元素中第K大的元素

     1 class Solution {
     2     public int findKthLargest(int[] nums, int k) {
     3         PriorityQueue<Integer> heap = new PriorityQueue<>();    // 最小堆
     4         for(int i : nums){
     5             heap.offer(i);
     6             if(heap.size() > k){
     7                 heap.poll();        // 维持堆的大小为k
     8             }
     9         }
    10         return heap.poll();
    11     }
    12 }

    力扣测试时间为:6ms, 空间为40.2MB

    复杂度分析:

    时间复杂度:一个维持堆大小为k的过程,所以时间复杂度为O(Nlogk)

    空间复杂度:O(k),也就是堆的大小

    思路三:

    借助快排的过程

     1 class Solution {
     2     public int findKthLargest(int[] nums, int k) {
     3         // 借助快排的过程
     4         return quickSort(nums, 0, nums.length - 1, nums.length - k);
     5     }
     6 
     7     public int partition(int[] nums, int left, int right){
     8         // 选取第一个元素为主元
     9         int pivot = nums[left];
    10         
    11         while(left < right){
    12             while(left < right && nums[right] >= pivot){
    13                 right--;
    14             }
    15             nums[left] = nums[right];
    16 
    17             while(left < right && nums[left] <= pivot){
    18                 left++;
    19             }
    20             nums[right] = nums[left];
    21         }
    22         nums[left] = pivot;
    23         return left;
    24     }
    25 
    26     public int quickSort(int[] nums, int left, int right, int k){
    27         // 如果经过一轮快排分区后主元位置刚好是k,那么可以直接退出了
    28         int mid = partition(nums, left, right);
    29         if(mid == k){
    30             return nums[k];
    31         }else if(mid > k){
    32             return quickSort(nums, left, mid - 1, k);
    33         }else{
    34             return quickSort(nums, mid + 1, right, k);
    35         }
    36     }
    37 }

    力扣测试时间为9ms, 空间为40.6MB

    复杂度分析:

    时间复杂度:每次将数组分成两段,只会选择其中一段进行partition操作,所以时间复杂度为O(N+N/2 + N/4 + 1) = ,所以时间复杂度为O(N)

    空间复杂度为:O(1)

     思路参考:

    https://leetcode-cn.com/problems/kth-largest-element-in-an-array/solution/shu-zu-zhong-de-di-kge-zui-da-yuan-su-by-leetcode/

  • 相关阅读:
    大前端工具集
    Python黑魔法,一行实现并行化
    MRPT
    ./configure 交叉编译库时所最常用到的配置
    Ubuntu16.04 ARM 编译 编译器版本和unordered_map map问题
    ubuntu 16.04 ARM glog移植
    Ubuntu16.04 ARM平台移植libcurl curl-7.63.0
    ubuntu16.04 ARM平台移植xmlrpc-c1.39.12
    ubunt 14.04 Could not find CMAKE_ROOT !!! CMake has most likely not been installed correctly. Modul
    ubuntu PCL的使用
  • 原文地址:https://www.cnblogs.com/hi3254014978/p/13121650.html
Copyright © 2020-2023  润新知