【第k小】树状数组 / 三路快排

215. 数组中的第K个最大元素

权值树状数组+二分
class Solution {
    int[] c;
    int up;
    public int findKthLargest(int[] nums, int k) {
        // 离散化
        // 去重+排序
        Set<Integer> set = new TreeSet<>();
        for(int i = 0; i < nums.length; ++ i ) set.add(nums[i]);

        // 离散
        Map<Integer, Integer> map = new HashMap<>();
        int[] disc = new int[set.size() + 1];
        up = 0;
        for(Integer val : set) {
            map.put(val, ++ up);
            disc[up] = val;
        }

        // 建树
        c = new int[up + 1];
        for(int i = 0; i < nums.length; ++i ) {
            add(map.get(nums[i]), 1);
        }
        k = nums.length - k + 1;
        return disc[kth(k)];
    }

    public int kth(int k) { // 第k小,返回下标
        int l = 1, r = up;
        int ans = -1;
        while(l <= r) {
            int mid = l + ((r - l) >> 1);
            int tar = getsum(mid);
            if(tar >= k) { // 由于可能存在相同元素,所以当大于的时候也可能是答案
                ans = mid;
                r = mid - 1;
            } else if(tar < k){
                l = mid + 1;
            }
        }
        return ans;
    }

    public int getsum(int x) {
        int ans = 0;
        while(x > 0) {
            ans += c[x];
            x -= lowbit(x);
        }
        return ans;
    }

    public void add(int x, int k) {
        while(x <= up) {
            c[x] += k;
            x += lowbit(x);
        }
    }

    public int lowbit(int x) {
        return x & -x;
    }
}
三路快速排序
class Solution {
    public int findKthLargest(int[] nums, int k) {
        return quickSort(nums, 0, nums.length, nums.length - k + 1);
    }

    public int quickSort(int[] nums, int l, int r, int k) {
        int pivot = nums[l];
        int i = l, lit = l, rit = r;
        while(i < rit) {
            if(nums[i] < pivot) {
                swap(nums, i ++ , lit ++ );
            } else if(nums[i] > pivot) {
                swap(nums, i, -- rit);
            } else {
                ++ i;
            }
        }
        if(lit == l &&  rit == r) return pivot;
        if(rit < k) return quickSort(nums, rit, r, k);
        if(rit > k) return quickSort(nums, l, rit, k);
        return pivot;
    }

    public void swap(int[] nums, int x, int y) {
        if(x == y) return;
        nums[x] = nums[x] ^ nums[y];
        nums[y] = nums[x] ^ nums[y];
        nums[x] = nums[x] ^ nums[y];
    }
}
posted @ 2024-04-19 15:36  沙汀鱼  阅读(5)  评论(0编辑  收藏  举报