剑指 Offer II 076. 数组中的第 k 大的数字(215. 数组中的第K个最大元素)

题目:

 

思路:

【0】这道题怎么说呢,不算难,考察的就是能不能默写快排和堆排,说直白点就是要去记,去背,要回默写,其他的没那么重要。

【1】堆排序

【2】快速排序

【3】基于哈希表的方式

代码展示:

基于哈希表的方式:

//时间1 ms击败94.61%
//内存41.6 MB击败53.84%
class Solution {
    public int findKthLargest(int[] nums, int k) {
        int min=nums[0];
        int max=nums[0];
        for(int num:nums){
            if(num<min){
                min=num;
            }
            if(num>max){
                max=num;
            }
        }
        int[] hash=new int[max-min+1];
        for(int num:nums){
            hash[num-min]++;
        }
        for(int i=max-min;i>=0;i--){
            k-=hash[i];
            if(k<=0){
                return i+min;
            }
        }
        return nums[0];
    }
}

 

快速排序的方式:

// 利用内置的排序
//时间23 ms击败54.77%
//内存48.9 MB击败60.47%
class Solution {
    public int findKthLargest(int[] nums, int k) {
        Arrays.sort(nums);
        return nums[nums.length-k];
    }
}

// 自己去实现的快速排序
//时间4 ms击败96.97%
//内存49 MB击败52.5%
class Solution {
    Random random = new Random();

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

    public int quickSelect(int[] a, int l, int r, int index) {
        int q = randomPartition(a, l, r);
        if (q == index) {
            return a[q];
        } else {
            return q < index ? quickSelect(a, q + 1, r, index) : quickSelect(a, l, q - 1, index);
        }
    }

    public int randomPartition(int[] a, int l, int r) {
        int i = random.nextInt(r - l + 1) + l;
        swap(a, i, r);
        return partition(a, l, r);
    }

    public int partition(int[] a, int l, int r) {
        int x = a[r], i = l - 1;
        for (int j = l; j < r; ++j) {
            if (a[j] <= x) {
                swap(a, ++i, j);
            }
        }
        swap(a, i + 1, r);
        return i + 1;
    }

    public void swap(int[] a, int i, int j) {
        int temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }
}

 

堆排序的方式:

// 利用内置的优先队列(里面已经实现了堆排序)
//时间57 ms击败18.90%
//内存51.3 MB击败9.55%
class Solution {
    public int findKthLargest(int[] nums, int k) {
//        PriorityQueue<Integer> queue = new PriorityQueue<Integer>(new Comparator<Integer>() {
//            @Override
//            public int compare(Integer o1, Integer o2) {
//                return o1 - o2;
//            }
//        });
        PriorityQueue<Integer> queue = new PriorityQueue<Integer>((o1, o2) -> o2 - o1);
        for (int num : nums){
            queue.add(num);
        }
        for (int i = 0; i < k-1; i++){
            queue.poll();
        }
        return queue.poll();
    }
}

// 自己去实现的堆排序
//时间2 ms击败72.67%
//内存41.6 MB击败43.26%
class Solution {
    public int findKthLargest(int[] nums, int k) {
        int heapSize = nums.length;
        buildMaxHeap(nums, heapSize);
        for (int i = nums.length - 1; i >= nums.length - k + 1; --i) {
            swap(nums, 0, i);
            --heapSize;
            maxHeapify(nums, 0, heapSize);
        }
        return nums[0];
    }

    public void buildMaxHeap(int[] a, int heapSize) {
        for (int i = heapSize / 2; i >= 0; --i) {
            maxHeapify(a, i, heapSize);
        } 
    }

    public void maxHeapify(int[] a, int i, int heapSize) {
        int l = i * 2 + 1, r = i * 2 + 2, largest = i;
        if (l < heapSize && a[l] > a[largest]) {
            largest = l;
        } 
        if (r < heapSize && a[r] > a[largest]) {
            largest = r;
        }
        if (largest != i) {
            swap(a, i, largest);
            maxHeapify(a, largest, heapSize);
        }
    }

    public void swap(int[] a, int i, int j) {
        int temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }
}

 

posted @ 2023-03-28 17:33  忧愁的chafry  阅读(21)  评论(0编辑  收藏  举报