使用快排求第K大数值

2020-03-13  本文已影响0人  C调路过
// note: 使用异或交互数值,需判断两数不相等
public class FindKthNum {

    public static void main(String[] args) {

        int[] arrs = new int[]{3, 2, 3, 1, 2, 4, 5, 5, 6};

        int t = new FindKthNum().findKthLargest(arrs, 4);
        System.out.print(t);
    }

    public int findKthLargest(int[] nums, int k) {
        return QuickSort(nums, 0, nums.length - 1, nums.length - k);
    }

    private int QuickSort(int[] arr, int first, int last, int target) {

        if (first > last) {
            return -1;
        }
        int p = paritition(arr, first, last);
        if (p == target) {
            return arr[p];
        }

        // 快排剪枝用于查找第K大的数,只需在其中一半进行查找
        int t = -1;
        if (target > p) {
            t = QuickSort(arr, p + 1, last, target);
        } else if (target < p) {
            t = QuickSort(arr, first, p - 1, target);
        }

        return t;
    }

    private int paritition(int[] arr, int first, int last) {
        // 随机化快排,优化?
        int idx = (int) (Math.random() * (last - first) + first);
        if (idx != first) {
            arr[idx] = arr[idx] ^ arr[first];
            arr[first] = arr[idx] ^ arr[first];
            arr[idx] = arr[idx] ^ arr[first];
        }
        int p = arr[first];
        int left = first + 1;
        int right = last;

        for (int i = left; i <= right; i++) {
            if (arr[i] >= p) {
                while (left <= right) {
                    if (arr[right] < p) {
                        arr[left] = arr[left] ^ arr[right];
                        arr[right] = arr[left] ^ arr[right];
                        arr[left] = arr[left] ^ arr[right];
                        left++;
                        right--;
                        break;
                    }
                    right--;
                }
            } else {
                left++;
            }
        }

        left--;
        if (p != arr[left]) {
            arr[first] = arr[left] ^ arr[first];
            arr[left] = arr[left] ^ arr[first];
            arr[first] = arr[left] ^ arr[first];
        }
        return left;
    }
}
上一篇 下一篇

猜你喜欢

热点阅读