网易16年研发实习生笔试题 - 寻找第K大
### 问题
有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数。
给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在。
输入样例
[1,3,5,2,2],5,3
输出样例
2
JavaCode
import org.junit.Test;public class FindKth {public int findKth(int[] a, int n, int K) {return find(a, 0, n-1, K);}//递归寻找数组中第K大的元素private int find(int[] a, int low, int high, int K) {int pivot = partition(a, low, high);if(pivot + 1 < K)//中轴位置少于K个,在右子数组中继续查找return find(a, pivot+1, high, K);else if(pivot + 1 > K)//中轴位置大于K个,在左子数组中继续查找return find(a, low, pivot-1, K);else//中轴元素正好是第K大的元素return a[pivot];}//将数组划分为两部分,左边较大,右边较小private int partition(int[] a, int low, int high) {// 将数组首元素作为每一轮比较的基准int pivotValue = a[low];while (low < high) {// 从右往左扫描,直到遇到比基准元素小的元素while (low < high && a[high] <= pivotValue)--high;// 将右子数组中不合格的元素放到左边不合格元素的位置(原元素已经移走)a[low] = a[high];// 从左往右扫描,直到遇到比基准元素大的元素while (low < high && a[low] >= pivotValue)++low;// 将左子数组中不合格的元素放到左边不合格元素的位置(原元素已经移走)a[high] = a[low];}// 将基准元素放到中间位置a[low] = pivotValue;// 返回数组的中轴位置return low;}@Testpublic void test() {int[] a = new int[]{1,2,3,3,4,5,6,6};int n=8;int k=6;System.out.println(findKth(a, n, k));}
}
说明
数组的K-th问题可以等价于top-K问题,其最典型的解法之一就是利用快排进行“剪枝“,因为快排在每一轮排序之后,能够将数组分成左右两部分,且左边部分的所有元素都大于右边部分的所有元素(假设是降序排列),每次都可以直接砍掉一部分元素,从而在下一轮排序中不需要考虑那些被砍掉的元素了,大大地较少了不必要的元素比较和交换。另外,如果要求最小的K个元素,这也可以采用类似的做法。常见排序算法的介绍可以参考排序算法代码总结。
由于快排的效率是不确定的,其时间复杂度最理想情况下是 O(nlogn) ,而最差为O(n^2)。后来大牛们提出了BFPRT算法,通过精心设计的 pivot 选取方法来改进快排,使得在最坏情形下也能保证线性时间复杂度!具体介绍可以参考NOALGO博客;
top-K问题另一种典型的解法是使用堆排序,可以始终维护一个K个节点的小根堆,K个节点就是当前已知的最大的K个元素,然后遍历数组中剩余的元素,如果大于根节点,则用这个元素替换掉根节点,再调整堆使其重新成为小根堆,这种解法的复杂度为O(nlogk),且适合于海量数据的外部排序。另外,top-K问题还可以采用部分选择排序等方法,具体的分析和讨论可以参考程序员编程艺术:第三章、寻找最小的k个数。
昨天的网易内推在线笔试题中有一道问答题就是考察的top-K问题。具体问题是:网易云音乐需要统计在3小时、1天、1周时间内被用户播放次数最多的K首歌曲,请设计相应的数据结构和数据库模型。这是一道非常不错的应用题,但我当时答得不太好,顺便再吐槽一下牛客网的考试系统!后来想想,我觉得这题不仅考察了top-K问题,还考察了基于top-K的应用拓展。对于最基础的每3小时的top-K歌曲榜单,可以采用上述的方式解决,对于1天的top-K歌曲榜单,我们可以直接基于已经统计好的当天的8张top-K榜单进行合并排序,也就是从8*K个中再选出前K个元素,这样数据量就少了很多了,但是需要注意这里的8张基础榜单中肯定会有重复元素,所以我们需要对不同时段榜单中的同名歌曲的播放次数先进行合并,这可以使用HashMap来实现;类似的,对于1周的top-K歌曲榜单,我们可以基于一周之内的7张top-K榜单进行合并排序。数据库设计方面,只需要每3小时统计一份完整的歌曲播放记录表,待排序之后得到一张top-K榜单并持久化到数据库中,这个时间段内完整的歌曲播放记录表就可以删除了,类似的,可以每天(周)统计、排序并记录一张当天(周)的top-K榜单。
网易16年研发实习生笔试题 - 寻找第K大相关推荐
- 网易笔试题 寻找第K大
有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数. 给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在. 测试样例: [1,3,5,2,2] ...
- 网易2016 实习研发工程师 [编程题]寻找第K大 and leetcode 215. Kth Largest Element in an Array...
传送门 有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数. 给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在. 测试样例: [1,3,5, ...
- 网易2016实习研发工程师编程题——寻找第K大
1.题目 有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数. 给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在. 测试样例: [1,3,5 ...
- 2022 3.17网易互娱研发岗笔试题锯齿数独题解
题面来自于某nb网友 简单题意 给定3∗33*33∗3的数独,给你固定的区域划分,除了满足基础数独还有满足区域划分的答案. 基础数独就是同行同列都是不同的数,这里的区域就是将3∗33*33∗3的数独划 ...
- 2014.03.16 网易游戏TTT计划实习生笔试题
注:这份试题是本人事后回忆的,题目可能会有出入,且给出的答案不一定正确,仅供参考,欢迎指正错误. 前面这些题是试卷的第I部分,试卷上面说第一部分达不到基本线直接淘汰,最终排名主要看II卷 I 卷 基础 ...
- 测试开发linux基础面试题,网易2018测试开发实习生笔试题记录
一.选择题 1.关于随机测试,以下哪一项说明是正确的? 随机测试是根据测试的经验在无测试用例的情况下进行的测试. 随机测试也是需要写一定的测试用例,但可以用例中没有的测试点. 随机测试不会产生测试冗余 ...
- 网易2019游戏研发工程师笔试题
第一题:计算个人所得税 #include <iostream> using namespace std; int main(){int t,n,result;float tmp;const ...
- 网易2016研发工程师笔试题
网易2016研发工程师笔试题 2015/12/9 11:25(网上收集整理的,参考答案在后面,若有错误请大神指出) 1. 执行指令find / -name "test.c",按ct ...
- 微软2012实习生笔试题及答案(望讨论)
微软的实习生笔试题,不是太难,算法的题好多,但是很多答案都不确定,欢迎大家讨论答案~ 答案:1.C(每迭代一次至少一个确定) 2.AC 3.ACE 4.A 5.C 6.C 7.D 8. AD 9.B ...
最新文章
- 跟我斗图,我用Python爬虫下载几个G的表情砸死你
- 用cmd运行java程序
- 剑指Offer——网易笔试之解救小易
- Cpp 对象模型探索 / 虚基类表作用
- 数模笔记_多变量最优化计算之随机搜索算法及建模案例
- 如何利用火狐获取网址中的提交链接
- spring学习(38):注入set类型
- ASCII Unicode GBK UTF的联系
- Java多线程学习三十四:使用 Future 有哪些注意点?Future 产生新的线程了吗
- 信息服务器恢复需要多少时间,云服务器灾难恢复的4个计划
- 用ssh从ubuntu系统向ubuntu系统服务器发送文件
- Android 学习路线
- 【贫穷网】PHP在线讨饭源码+支付宝当面付DEMO+自动在线要饭源码+安装教程
- 连续值特征分桶区间设置
- 分布式 b2b b2c o2o电子商务 云平台
- HTML转EXE工具(HTML App Build)最新版
- 电脑从新分盘(软件)
- 海子诗《面朝大海,春暖花开》
- html写表格最左最右的边框,excel怎么制作个人账本? excel账本的详细制作图文教程...
- VUE 切换页面后点击按钮没有反应