数组的第K大值

寻找第K大

http://www.nowcoder.com/questionTerminal/e016ad9b7f0b45048c58a9f27ba618bf

二分查找和堆查找

一、二分查找是利用快速排序的二分特点
利用快排在排序时,把数组分成两部分,一部分小于一个值,另一部分大于这个值的特点
将数组用快排从大到小排序,取temp值为数组的第一个数a[start],那么经过一轮调整之后,数组左边的所有值大于或等于temp,数组右边的所有值都小于或等于temp,假设此时temp是数组第i个数。
如果i正好等于K,那么temp就是第K大值
如果i大于K,那么说明第K大值在数组左边,则继续在左边查找
如果i小于K,那么说明第K大值在数组的右边,继续在右边查找
每一轮排序都重复上述步骤,直到找到第K大值。

import java.util.*;

public class Finder {
    public int findKth(int[] a, int n, int K) {
        return quickSort(a, 0, n - 1, K);
    }

    private int quickSort(int[] a, int start, int end, int k) {
        int temp = a[start];
        int s = start, e = end;
        while (s < e) {
            while (s < e && temp >= a[e]) e --;
            a[s] = a[e];
            while (s < e && temp <= a[s]) s ++;
            a[e] = a[s];
        }
        a[s] = temp;
        if (s == k - 1) {
            return a[s];
        } else if (s > k - 1) {
            return quickSort(a, start, s - 1, k);
        } else {
            return quickSort(a, s + 1, end, k);
        }
    }
}

二、堆查找是利用堆排序的特点
比较直接,堆排序时,如果是从小到大排序则是先建立一个大顶堆,然后依次从大到小排列各值
第K个排到的值就是第K大值

import java.util.*;

public class Finder {
    public int findKth(int[] a, int n, int K) {
        // write code here
        // build heap
        for (int i = n / 2 - 1; i >= 0; i--) {
            heapify(a, n, i);
        }
        // sort top K
        for (int i = n - 1; i >= n - K; i--) {
            swap(a, 0, i);
            heapify(a, i, 0);
        }
        return a[n-K];
    }

    private void heapify(int[] a, int n, int k) {
        int temp = a[k];
        int t = 2 * k + 1;
        while (t < n) {
            if (t + 1 < n && a[t] < a[t+1]) {
                t ++;
            }
            if (temp < a[t]) {
                a[k] = a[t];
                k = t;
                t = 2 * k + 1;
            } else {
                break;
            }
        }
        a[k] = temp;
    }

    private void swap(int[] a, int i, int j) {
        int temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }
}
全部评论
超时了!
点赞 回复 分享
发布于 2022-07-03 10:47
快排那里又帮助,感谢
点赞 回复 分享
发布于 2021-07-15 15:27

相关推荐

不愿透露姓名的神秘牛友
12-16 15:57
小鹏汽车 java后端 22*15(固定13,2个月年终) 硕士211
点赞 评论 收藏
分享
10-28 17:30
已编辑
华东交通大学 Java
想进开水团喝开水:字节的hr的本职工作就是黄金矿工
秋招笔试记录
点赞 评论 收藏
分享
不知道怎么取名字_:两个方向 1.简历针对性准备下 2.面试前也需要准备的 主要还是要看各个公司需求,看公司行业和岗位描述,那里面已经写了对技术的需求,一份简历,不可能和所有嵌入式岗位都匹配的
投递北京经纬恒润科技股份有限公司等公司6个岗位
点赞 评论 收藏
分享
评论
18
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务