zoukankan      html  css  js  c++  java
  • ( 快排) leetcode 215. Kth Largest Element in an Array

    题目:在无序的数组中找到第k大的元素,也就是若长度为n的数组从小到大排列时,下标为n-k的元素。

    注意Example2:第4大的元素是4,也就是数组中出现的两个5分别是第2大和第3大的数字。                   

    解法一:直接利用sort函数排序后,取第k大的元素。

    class Solution {
    public:
        int findKthLargest(vector<int>& nums, int k) {
            sort(nums.begin(), nums.end());
            return nums[nums.size() - k];
        }
    };
    class Solution {
    public:
        int findKthLargest(vector<int>& nums, int k) {
            sort(nums.begin(), nums.end(),greater<int>());
            return nums[k-1];
        }
    };

    解法二:快排

    时间复杂度是:O(n)

    注意几个问题:

    1)k的取值:是不变的啊! 不会因为递归时在privot的左边或者右边寻找而改变,因为nums的长度n是不变的,元素的下标也是不变的;

    2)partition函数递归调用自己时是要加return的!不然会报错。

    class Solution {
    public:
        
         int partition(vector<int>& nums, int k, int l, int r){
           int n = nums.size();
            swap(nums[l],nums[rand()%(r-l+1)+l]);   //生成随机数
            int p = nums[l];
            
            //nums[l+1...i) <=v ; nums(j...r] >=v i和j 是需要考察的元素,所以是开区间
            int i = l+1, j = r;     //初始定义区间为空
            while(true){
                while(i<=r && nums[i]<p)
                    i++;
                while(j>=l+1 && nums[j]>p)
                    j--;
                if(i>j) break;
                swap(nums[i], nums[j]);
                i++;
                j--;
            }
            swap(nums[l], nums[j]);
            
            if(j == n-k) return nums[j];
            else if(j < n-k) return partition(nums, k, j+1,r);
            else return partition(nums, k, l, j-1);
            
        }
        
        int findKthLargest(vector<int>& nums, int k) {
            srand(time(NULL));
            int n = nums.size();
            return partition(nums, k, 0, n-1);
            
        }
    
    };

     终于把快排思想的写对了,前一天晚上一直在报错,因为上面提到的两个点没有想明白,还是早上效率高 :)

    解法二:思路是将比privot大的元素放到privot左边, 小的放到privot右边。

    class Solution {
    public:
        int quick_sort(vector<int>& nums, int k, int left, int right){
            swap(nums[left], nums[left + rand()%(right-left+1)]);  //随机取在nums中取一个数 与 nums[left]交换位置
            int p = nums[left];
            int i = left+1, j = right;
            while(1){
                while( i<=right && nums[i] >= p)  // p = nums[left]
                    i++;
                while( j>=left+1 && nums[j] <= p)
                    j--;
                if(i>=j)
                    break;
                swap(nums[i], nums[j]);  
                i++;
                j--;
            }
           // swap(nums[left], nums[j]);  
            swap(p, nums[j]);    // 若交换p和nums[j] 因为还需要把 p 的值再赋给nums[left]
            nums[left] = p;
            
            if(j == k-1)
                return nums[j];
            else if(k-1 > j)
                // k-1为4,j为3时
                // 第4大的数 < 第3大的数 数组是从大到小排序 故从右半部分寻
                return quick_sort(nums, k, j+1, right);
            else
                return quick_sort(nums, k, left, j-1);
        }    
        
        int findKthLargest(vector<int>& nums, int k) {
           return quick_sort(nums, k, 0, nums.size()-1); 
        }
    
    };
  • 相关阅读:
    nyoj-115-城市平乱(dijkstra算法)
    如何在大学里脱颖而出(其二)
    P6880-[JOI 2020 Final]オリンピックバス【最短路】
    P6847-[CEOI2019]Magic Tree【dp,线段树合并】
    P6800-[模板]Chirp Z-Transform【NTT】
    P5470-[NOI2019]序列【模拟费用流】
    P6563-[SBCOI2020]一直在你身旁【dp,单调队列】
    CF587F-Duff is Mad【AC自动机,根号分治】
    P7405-[JOI 2021 Final]雪玉【二分】
    互斥锁,IPC队列
  • 原文地址:https://www.cnblogs.com/Bella2017/p/10128957.html
Copyright © 2011-2022 走看看