Quick Select 快速选择算法

关于我的 Leetcode 题目解答,代码前往 Github:https://github.com/chenxiangcyr/leetcode-answers


快速选择是一种从无序列表找到第k小元素的选择算法。它从原理上来说与快速排序有关。同样地,它在实际应用是一种高效的算法,具有很好的平均时间复杂度,然而最坏时间复杂度则不理想。
快速选择及其变种是实际应用中最常使用的高效选择算法。

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

示例:
从数组中找出第 k 小的元素:

// find the kth **smallest** element in an unsorted array
public int quickSelect(int[] nums, int k) {
    int i = 0;
    int j = nums.length - 1;
    
    while(i <= j) {
        int partitionIdx = partition(nums, i, j);
        
        if((k - 1) == partitionIdx) {
            return nums[partitionIdx];
        }
        else if((k - 1) < partitionIdx) {
            j = partitionIdx - 1;
        }
        else {
            i = partitionIdx + 1;
        }
    }
    
    return 0;
}

// same as qucik sort
public int partition(int[] nums, int start, int end) {
    if(start == end) {
        return start;
    }
    
    int pivot = nums[start];
    
    while(start < end) {
        // find first smaller element from right
        while(start < end && nums[end] >= pivot) {
            end--;
        }
        nums[start] = nums[end];
        
        // find first larger element from left
        while(start < end && nums[start] <= pivot) {
            start++;
        }
        nums[end] = nums[start];
    }
    
    nums[start] = pivot;
                         
    return start;
}

引用:


快速选择

你可能感兴趣的:(Quick Select 快速选择算法)