zoukankan      html  css  js  c++  java
  • 经典算法之快速选择算法

    相信快速排序算法这种经典的算法大家并不陌生。但是基于快速算法的各种变形,你了解吗?

    其中很重要的一种变形就是快速选择算法, 通常用来在未排序的数组中寻找第k小/第k大的元素。快速选择及其变种是实际应用中最常使用的高效选择算法。

    快速选择的总体思路与快速排序一致,选择一个元素作为基准来对元素进行分区,将小于和大于基准的元素分在基准左边和右边的两个区域。不同的是,快速选择并不递归访问双边,而是只递归进入一边的元素中继续寻找。这降低了平均时间复杂度,从O(n log n)至O(n),不过最坏情况仍然是O(n2)。

    lc上一道题:

    Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.

    下面的解法注释详细,能很好的理解快速选择算法,这个可以当作模版记下来。面试时能一次ac不出错吗?其实不是那么容易。记住的关键在于深刻的理解。

    class Solution {
        /**
     *  解法0. 堆 O(klogn)
     *  解法1. 快速选择: O(n)
     */
    
        public int findKthLargest(int[] nums, int k) {
            if (nums.length == 0 || nums == null) return 0;
            int left = 0, right = nums.length - 1;
            while (true) {
                int position = partition(nums, left, right);
                if (position == k - 1) return nums[position]; //每一轮返回当前pivot的最终位置,它的位置就是第几大的,如果刚好是第K大的数
                else if (position > k - 1) right = position - 1; //二分的思想
                else left = position + 1;
            }
        }
    
        private int partition(int[] nums, int left, int right) {
            int pivot = left;
            int l = left + 1; //记住这里l是left + 1
            int r = right;
            while (l <= r) {
                while (l <= r && nums[l] >= nums[pivot]) l++; //从左边找到第一个小于nums[pivot]的数
                while (l <= r && nums[r] <= nums[pivot]) r--; //从右边找到第一个大于nums[pivot]的数
                if (l <= r && nums[l] < nums[pivot] && nums[r] > nums[pivot]) {
                    swap(nums, l++, r--);
                }
            }
            swap(nums, pivot, r); //交换pivot到它所属的最终位置,也就是在r的位置,因为此时r的左边都比r大,右边都比r小
            return r; //返回最终pivot的位置
        }
    
        private void swap(int[] nums, int l, int r) {
            int tmp = nums[l];
            nums[l] = nums[r];
            nums[r] = tmp;
        }
    
        
    }
  • 相关阅读:
    思念
    空白
    curl json string with variable All In One
    virtual scroll list All In One
    corejs & RegExp error All In One
    socket.io All In One
    vue camelCase vs PascalCase vs kebabcase All In One
    element ui 表单校验,非必填字段校验 All In One
    github 定时任务 UTC 时间不准确 bug All In One
    input range & color picker All In One
  • 原文地址:https://www.cnblogs.com/shawshawwan/p/9220818.html
Copyright © 2011-2022 走看看