经典算法之快速选择算法

经典算法之快速选择算法相信快速排序算法这种经典的算法大家并不陌生。但是基于快速算法的各种变形,你了解吗? 其中很重要的一种变形就是快速选择算法,<!?xml version="1.0" encoding="UTF-8"?> 通常用来在未排序的数组中寻找

经典算法之快速选择算法"

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

 

其中很重要的一种变形就是快速选择算法, 通常用来在未排序的数组中寻找第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;
    }

    
}

 

今天的文章经典算法之快速选择算法分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/56417.html

(0)
编程小号编程小号
上一篇 2023-08-26 19:17
下一篇 2023-08-26

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注