- 浏览: 8058 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
liuxuejin:
paohui01 写道taojingrui 写道这样的考题,我 ...
一道腾讯面试题:从大量数字中取出 top 100 -
liuxuejin:
taojingrui 写道这样的考题,我遇过多次了。其实这类题 ...
一道腾讯面试题:从大量数字中取出 top 100 -
jeho0815:
import java.util.ArrayList;impo ...
一道腾讯面试题:从大量数字中取出 top 100 -
沙舟狼客:
这题对于我初学者来说有点难度!!!
一道腾讯面试题:从大量数字中取出 top 100 -
jeho0815:
楼主的排序时错误的。。。重复数据竟然没算
一道腾讯面试题:从大量数字中取出 top 100
最近有同事去腾讯面试,其中一个排序算法题:从1亿个数字中取出最大的100个. 我感觉用位图排序是比较合适的.位图排序的特点是用内存空间换取CPU时间.代码如下:
import java.util.Random;
public class Top100 {
public static int[] getTop100(int[] inputArray) {
int maxValue = Integer.MIN_VALUE;
for (int i = 0; i < inputArray.length; ++i) {
if (maxValue < inputArray[i]) {
maxValue = inputArray[i];
}
}
byte[] bitmap = new byte[maxValue+1];
for (int i = 0; i < inputArray.length; ++i) {
int value=inputArray[i];
bitmap[value] = 1;
}
int[] result = new int[100];
int index = 0;
for (int i = maxValue; i >= 0 & index < 100; --i) {
if (bitmap[i] == 1) {
result[index++] = i;
}
}
return result;
}
public static void main(String[] args) {
int numberCount = 90000000;
int maxNumber = numberCount;
int inputArray[] = new int[numberCount];
Random random = new Random();
for (int i = 0; i < numberCount; ++i) {
inputArray[i] = Math.abs(random.nextInt(maxNumber));
}
System.out.println("Sort begin...");
long current = System.currentTimeMillis();
int[] result = Top100.getTop100(inputArray);
System.out.println(System.currentTimeMillis() - current);
for (int i = 0; i < result.length; ++i) {
System.out.print(result[i] + ",");
}
}
}
我的机子是配置是CPU:Intel(R) Pentium(R) M processor 1.60GHZ,512M内存. 运行结果如下
1千万:1.297秒
2千万: 2.906秒
3千万:4.578秒
4千万:6.203秒
5千万:7.875秒
6千万:9.953秒
7千万:11.407秒
8千万:26.921秒
9千万:31.953秒
当运行到1亿数据时,机子几乎就没有反应了,这可能是物理内存已经耗尽,用虚拟内存了.
欢迎交流!
评论
方法1
基本上,这道题如果不考虑数据录入,调用两次循环,上亿的数字中找top100,用不到1秒应该就够了。
提示:
1.考虑用位(bit)数组,1亿bit需要多少内存?100000000/1024/1024/8<12M,就是10亿数字,也不到120M
2.一个bit的数组大小为1亿,bit[i]=0,表示i数据不存在,bit[i]=1,表示i数据存在。(循环1次1亿数据,不用比较数据大小)
3.最后找到bit数组中,bit[i]=1且top100 i(循环1次)
方法2
建立一张数据库表,把上亿数据录入数据库,有索引的情况下,在上亿数据中找top100,也是很快的(不考虑数据录入数据库的时间)
int[] nums = new int[100000000];
内存溢出拉?
java int占32位 相当于4个字节
1亿个int占4亿个字节....
4亿个字节 差不多相当于380M 能溢出?1G的内存就够用
第一种方法 看不懂
使用TreeSet感觉是最好解决方法拉(参考skzr.org的代码)
如果觉得内存会不够用的话
数据放到文件里面读取好拉
内存永远不会溢出
4亿个字节只有380M!求怎么算的?
方法1
基本上,这道题如果不考虑数据录入,调用两次循环,上亿的数字中找top100,用不到1秒应该就够了。
提示:
1.考虑用位(bit)数组,1亿bit需要多少内存?100000000/1024/1024/8<12M,就是10亿数字,也不到120M
2.一个bit的数组大小为1亿,bit[i]=0,表示i数据不存在,bit[i]=1,表示i数据存在。(循环1次1亿数据,不用比较数据大小)
3.最后找到bit数组中,bit[i]=1且top100 i(循环1次)
方法2
建立一张数据库表,把上亿数据录入数据库,有索引的情况下,在上亿数据中找top100,也是很快的(不考虑数据录入数据库的时间)
我想问问,你的bit数组在java是如何构建的?
import java.util.List;
import java.util.Random;
public class GetTop100 {
private static List<Integer> result = new ArrayList<Integer>();
/**
* @param args
*/
public static void main(String[] args) {
int count = 100000000; //要处理的数据量
int maxNumber = count;
int inputArray[] = new int[count];
Random random = new Random();
for (int i = 0; i < count; ++i) {
inputArray[i] = Math.abs(random.nextInt(maxNumber)); //随机生成的数组
}
System.out.println("Sort begin...");
long current = System.currentTimeMillis();
getTop100(inputArray);
System.out.println(System.currentTimeMillis() - current + " result:"+result.size());
for (int i = 0; i < result.size(); ++i) {
System.out.print(result.get(i) + ",");
}
}
private static void getTop100(int[] inputArray) { //得到前100的数据
for(int i = 0 ; i < inputArray.length ; i ++){
if(i < 100){
add(inputArray[i]);//前100个位自动插入
}else if(inputArray[i] > result.get(0)){
insert(inputArray[i]);//后面的为先删除再插入
}
}
}
private static void insert(int value) {
result.remove(0);//删除第一个
int index = result.size();//以下同添加
if(value > result.get(index-1)){
result.add(value);
}else{
for(int i = 0 ; i < index ; i++){
if(value <= result.get(i)) {
result.add(i, value);
return;
}
}
}
}
private static void add(int value) {
int index = result.size();
if(result.size() == 0){
result.add(value); //当为第一个时直接添加
}else if(value > result.get(index-1)){
result.add(value); //当为最后一个,就是最大的时候,也直接添加
}else{ //在lsit中间,则要遍历查找要出入的地方
for(int i = 0 ; i < index ; i++){
if(value <= result.get(i)) {
result.add(i, value);
return;
}
}
}
}
}
重新写的一个,解决了重复数据的问题。并且时间为两秒多一点点!
import java.util.Set;
import java.util.TreeSet;
public class TestSF {
public static Set<Integer> getTop100(int[] inputArray) {
TreeSet<Integer> top100 = new TreeSet();
for (int i = 0; i < inputArray.length; i++) {
if (top100.size()<100){
top100.add(inputArray[i]);
}else if ((Integer)top100.first()<inputArray[i]){
Object obj = top100.first();
top100.remove(obj);
top100.add(inputArray[i]);
}
}
return top100;
}
public static void main(String[] args) {
int numberCount = 100000000;
int maxNumber = numberCount;
int inputArray[] = new int[numberCount];
Random random = new Random();
for (int i = 0; i < numberCount; ++i) {
inputArray[i] = Math.abs(random.nextInt(maxNumber));
}
System.out.println("Sort begin...");
long current = System.currentTimeMillis();
Set<Integer> result = TestSF.getTop100(inputArray);
System.out.println("Spend time:"+(System.currentTimeMillis() - current));
}
}
如果有重复数据怎么办?
Spend time:2375
数组值都是0,当然是这样咯。
import java.util.Set;
import java.util.TreeSet;
public class TestSF {
public static Set<Integer> getTop100(int[] inputArray) {
TreeSet<Integer> top100 = new TreeSet();
for (int i = 0; i < inputArray.length; i++) {
if (top100.size()<100){
top100.add(inputArray[i]);
}else if ((Integer)top100.first()<inputArray[i]){
Object obj = top100.first();
top100.remove(obj);
top100.add(inputArray[i]);
}
}
return top100;
}
public static void main(String[] args) {
int numberCount = 100000000;
int maxNumber = numberCount;
int inputArray[] = new int[numberCount];
Random random = new Random();
for (int i = 0; i < numberCount; ++i) {
inputArray[i] = Math.abs(random.nextInt(maxNumber));
}
System.out.println("Sort begin...");
long current = System.currentTimeMillis();
Set<Integer> result = TestSF.getTop100(inputArray);
System.out.println("Spend time:"+(System.currentTimeMillis() - current));
}
}
速度果然很快
1千万数据
Sort begin...
Spend time:266
不过再多的话我电脑就抛异常了,想来是内存不够了。。
java.lang.OutOfMemoryError: Java heap space
public class findValue { public static void main(String[] args){ int max = 10000*10000; int length=100; int ints[] = new int[max]; Random random = new Random(); for (int i=0;i<max;i++) { ints[i]=Math.abs(random.nextInt(max)); } List<Integer> list = new ArrayList(); long start = System.currentTimeMillis(); int size=0; int value=0; list.add(ints[0]); for(int i=1;i<max;i++){ value=ints[i]; size=list.size(); if(value<list.get(size-1)){ if(size<length){ list.add(value); } continue; }else if(value>list.get(0)){ list.add(0,value); if(size==length){ list.remove(size); } continue; } for(int j=0;j<size;j++){ if(value>list.get(j)){ //如果不需要排除重复数字,则去掉该判断 if(j>0&&value!=list.get(j-1)){ list.add(j,value); if(size==length){ list.remove(size); } } break; } } } System.out.println("time:"+(System.currentTimeMillis()-start)); System.out.println(list); TreeSet<Integer> set = new TreeSet(); set.addAll(list); System.out.println(set.size()+":"+list.size()); if(set.size()!=list.size()){ System.out.println("error"); } int i=0; for(Iterator<Integer> it=set.iterator();it.hasNext();){ value=it.next(); System.out.println(value+":"+list.get(list.size()-1-i)); if(value!=list.get(list.size()-1-i)){ System.out.println("error"); break; } i++; } } }
E2160 3G
time:2453
BitSet bset = new BitSet(max);
Random random = new Random();
for(int i=0;i<max;i++){
bset.set(Math.abs(random.nextInt(max)));
}
System.out.println("加载完毕!");
long lo = System.currentTimeMillis();
int[] top100 = new int[100];
int location = 0;
for(int i=max;i>=0;i--){
boolean bool = bset.get(i);
if(location==100){
break;
}
if(bool){
top100[location] = i;
location++;
}
}
System.out.println("花费:"+(System.currentTimeMillis()-lo));
for(int i=0;i<100;i++){
System.out.println(top100[i]);
}
这样才对。
BitSet bset = new BitSet(max);
Random random = new Random();
for(int i=0;i<max;i++){
bset.set(Math.abs(random.nextInt(max)));
}
System.out.println("加载完毕!");
long lo = System.currentTimeMillis();
int[] top100 = new int[100];
int location = 0;
for(int i=0;i<max;i++){
boolean bool = bset.get(i);
if(location==100){
break;
}
if(bool){
top100[location] = i;
location++;
}
}
System.out.println("花费:"+(System.currentTimeMillis()-lo));
for(int i=0;i<100;i++){
System.out.println(top100[i]);
}
花费:0
List<Integer> lst = new ArrayList<Integer>();
int numberCount = 1000000000;
int maxNumber = numberCount;
Random random = new Random();
for (int i = 0; i < numberCount; i++) {
int randomInt = random.nextInt(maxNumber);
Integer inte = new Integer(randomInt);
if (set.contains(inte))
{
lst.add(inte);
}
if (set.size() < 100)
{
set.add(inte);
}
else
{
if (set.first().intValue() < randomInt)
{
set.remove(set.first());
set.add(randomInt);
}
}
}
Iterator iterator = set.iterator();
while(iterator.hasNext()) {
lst.add((Integer)iterator.next());
}
Collections.sort(lst);
for (int i = 0; i < 100; i++)
{
System.out.println(i + ":" + lst.get(lst.size() - i - 1));
}
这段代码貌似十几秒就可以了,每1KW用时不到2S。
import java.util.Random;
public class Top100 {
private static Node head = null;
private static Node end = null;
private static Node tempNode = null;
private static Node node = null;
public static int[] getTop100(int[] inputArray) {
int result[] = new int[100];
int k = 100;
if (inputArray.length < 100) {
k = inputArray.length;
}
for (int i = 0; i < 100; ++i) {
result[i] = inputArray[i];
}
Arrays.sort(result);
for (int i = k - 1; i >= 0; i--) {
node = new Node(result[i], tempNode);
if (i == k - 1) {
head = node;
} else {
tempNode.right = node;
}
if (i == 0) {
end = node;
}else{
tempNode = node;
}
}
tempNode = end ;
for (int i = 100; i < inputArray.length; i++) {
int tempValue = inputArray[i];
if (tempValue <= end.value) {
continue;
}else{
tempNode = end;
setValue(inputArray[i]) ;
}
}
for (int i = 0; i < 100; i++) {
if (i == 0) {
node = head;
} else {
node = node.right;
}
result[i] = node.value;
}
return result;
}
private static void setValue(int tempValue) {
if (tempNode.value < tempValue) {
tempNode = tempNode.left;
//最大的
if(tempNode==null){
node = new Node(head,tempValue );
head.left = node ;
head = node ;
removeEnd() ;
}else{
setValue(tempValue);
}
} else if (tempNode.value != tempValue) {
node = new Node(tempValue, tempNode);
//要替代end
if(tempNode.right==end){
end.left.right = node ;
end = node ;
}else{
try {
tempNode.right.left = node;
} catch (Exception e) {
// TODO Auto-generated catch block
System.err.println(tempNode.right) ;
e.printStackTrace() ;
System.exit(0) ;
}
tempNode.right = node;
removeEnd() ;
}
}
}
private static void removeEnd(){
end = end.left ;
end.right = null ;
}
public static void main(String[] args) {
int numberCount = 1000000;
int maxNumber = numberCount;
int inputArray[] = new int[numberCount];
Random random = new Random();
for (int i = 0; i < numberCount; ++i) {
inputArray[i] = Math.abs(random.nextInt(maxNumber));
}
System.out.println("Sort begin...");
long current = System.currentTimeMillis();
int[] result = Top100.getTop100(inputArray);
System.out.println(System.currentTimeMillis() - current + "ms");
for (int i = 0; i < result.length; ++i) {
System.out.print(i + "." + result[i] + ",");
}
}
}
class Node {
protected int value;
protected Node left;
protected Node right;
public Node(int value) {
this.value = value;
}
public Node(int value, Node left) {
this.value = value;
this.left = left;
}
public Node(Node right, int value) {
this.right = right;
this.value = value;
}
}
数组A越来越接近最后要的100个大数,所以后面的插进来的数字小于数组最小值的概略最大,大于数组最大值的概略最小。这样倒着往上比较,插入到合适的位置,然后删除最小值。
纯属理论分析。也许最小顶堆最靠谱!
------------------------------------------
说一下楼主的方法,实际上是基数排序的变种,所需空间取决于给定数字中的最大值,如果遇见一个long型的大数字估计就死了。还有楼主没有统计重复数字。
at Top100.main(Top100.java:62)
楼主的程序好像没有经过测试的
相关推荐
这道2011年腾讯校招的面试题虽然没有明确的问题描述,但从标签中我们可以推测,它可能涉及C++、.NET、Java这三种编程语言中的某一方面,或者是关于算法设计与分析。面试题通常旨在考察候选人的思维能力、编程基础...
腾讯面试题解析.pdf 本资源是一份详细的腾讯面试题解析文档,涵盖了 Android 面试题、网络基础、常用三方库、算法基础等多个方面的知识点。下面是对该文档的详细解析: 计算机基础面试题 在计算机基础面试题部分...
《腾讯面试题与笔试题详解》 在求职的道路上,面试和笔试是必不可少的环节,尤其是对于技术人才来说,能够顺利通过大公司的面试更是彰显个人实力的重要标志。本压缩包包含两份珍贵的资料——“腾讯笔试题专辑(含...
腾讯研究院:PDF 腾讯数字生活报告
最新腾讯PHP面试题1. php 的垃圾回收机制 PHP 可以自动进行内存管理,清除不需要的对象。 PHP 使用了引用计数 (reference counting) GC 机制。 每个对象都内含一个引用计数器 refcount,每个 reference 连接到对象,...
腾讯的面试题则关注了SVM的优化函数公式、随机森林的原理、XGBoost的优势等。SVM的优化函数是二次规划问题,随机森林通过构建多棵决策树来提高模型的鲁棒性。 蔚来和虾皮的面试题则包含了链表问题、二叉树遍历和数...
在腾讯算法面试题中,要求选出64匹马中最快的四匹,需要使用排序算法来解决这个问题。排序算法是计算机科学中的一种算法,用于对一组数据按照特定的顺序进行排序。排序算法的应用场景非常广泛,在数据分析、机器学习...
阿里面试20题 百度面试10题 华为面试10题 京东面试13题 腾讯面试37题 头条面试10题 项目经理面试常遇问题 经典面试题 程序员 IT经理 项目经理 面试题 研发经理 高级程序员 经典面试题
一年之前的10月14日,一个名叫July (头像为手冢国光)的人在一个叫csdn的论坛上开帖分享微软等公司数据结构+算法面试100题,自此,与上千网友一起做,一起思考,一起解答这些面试题目,最终成就了一个名为:结构之...
以下是一些具体的面试题及其解析: 1. 宏定义比较大小:`#define BIG_THAN(a, b) (((b) – (a)&(0x1))>>31)` 这个宏利用了二进制的位运算来比较两个数的大小。当a大于b时,b-a会产生负数,而负数的最高位(符号位)...
### 腾讯面试题笔试题解析 #### 领域背景 在IT行业中,面试题目不仅是对求职者技能的一种考验,也是企业筛选合适人才的重要工具。本篇将基于提供的标题、描述、部分问题及其答案,深入分析这些知识点,帮助读者更...
ava工程师面试题大全-100%公司笔试题你都能碰到几个.docx Java开发工程师上机笔试题.docx Java开发求职面试题.docx Java开发笔试题.docx Java数据结构类面试题.docx Java数据结构题.docx Java笔试面试宝典.docx Java...
在腾讯的前端面试中,面试官可能会关注一系列关键知识点,这些知识点涵盖了前端开发的基础到进阶内容。以下是对这些知识点的详细解释: 1. **JSONP原理**:JSONP(JSON with Padding)是一种解决跨域数据获取的问题...
【腾讯09年测试面试题解析】 面试题1:QQ登陆号码边界值测试有哪些 边界值测试是一种重要的软件测试方法,主要针对输入或输出范围的边界条件进行测试。对于QQ登录号码,边界值可能包括最小值(如0,因为QQ号通常从0...
【腾讯Java面试题】 在Java领域,面试是评估求职者技术实力的重要环节,而腾讯作为中国互联网巨头之一,其Java面试题往往具有很高的参考价值。这些题目不仅涵盖基础语法、数据结构、算法、多线程、JVM优化等多个...
腾讯研究院发布的《2019腾讯数字生活报告》深入分析了数字技术在人们日常生活中的渗透和应用,揭示了它们是如何满足人类的生存、关系以及发展需求,并进一步塑造个人生活路径的。报告基于马斯洛的需求层次理论,将...
报告“腾讯:中小企业数字化转型路径报告”探讨了在全球新冠疫情背景下,数字化转型对于中小企业的重要性,以及中国在此过程中的挑战和机遇。数字化转型不仅是企业适应新环境的必然选择,也是国家经济发展的重要推动...
网盘下载pdf文件,包括常见前端面试题汇总,百度、阿里、腾讯校招面试题汇总,网盘下载pdf文件,65个文件
10道腾讯的Java面试题10道腾讯的Java面试题10道腾讯的Java面试题10道腾讯的Java面试题10道腾讯的Java面试题10道腾讯的Java面试题
本资源“2022年最新(腾讯)前端面试题真题解析”汇聚了最新的腾讯前端面试题,旨在帮助求职者更好地准备面试,提升成功入职的可能性。 面试题的解析通常会涵盖以下几个关键领域: 1. **基础概念**:面试题会涉及...