首先感谢面试官,看了我的博客,并认真读了我的博客,并针对求第三大数的算法,给出了我宝贵的建议;
对于我来说,这样才有有意,这样学习才能成长,这样进步才能更快;
首先题目很简单,就是求若干个数中第三个数是多少?我第一次写的程序如下:
package test;
/**
* @title 求一个数组中第三大数是多少
* @author 郑云飞
* @date 2014-04-13
*
*/
public class ArrayDemo{
public static void main(String[] args){
int arr[]={1,3,5,7,23,122,2344};
int x=show(arr);
System.out.println("第三大数="+x);
}
/**
* @author 郑云飞
* @date 2014-04-13
* @param arr 数组
* @return 第三大数
*/
public static int show(int arr[]){
for(int i=0;i<arr.length-1;i++){
for(int j=i+1;j<arr.length;j++){
if(arr[i]>arr[j]){
temp(arr,i,j);//交换位置
}
}
}
return arr[arr.length-3];
}
/**
* @title 交换位置
* @param arr 数组名
* @param a 参数a
* @param b 参数b
*/
public static void temp(int arr[],int a,int b){
int t=arr[a];
arr[a]=arr[b];
arr[b]=t;
}
}
面试官看过之后说:我的代码是先排序再找出第三大数,效率不是很高,让我继续琢磨一下,并给了我温馨提示:说并不需要全体排序就能找出来。
看过短信之后,我首先回忆了一下,当初在凤凰汇咖啡厅的时候,面试官曾经给了我暗示。我按照他当初给我的提示,反复思考着,最后想到了用冒泡排序实现升序的过程,只执行三次排查即可,第三大的数会排到倒数第3位的位置,改进后的代码如下:
package com.yting.hadoop.rpc;
/**
* @title 求一个数组中第三大数是多少
* @author 郑云飞
* @date 2014-04-16
*
*/
public class ArrayDemo {
public static void main(String[] args) {
int a[]={10,9,8,7,6,5,4,3,2,1};//随便定义一个数组,并初始化
int i,j;
//用冒泡排序实现升序的过程,只执行三次排查即可,第三大的数会排到倒数第3位的位置
for(i=0;i<3;i++)
{
for(j=0;j<10-i-1;j++)
{
if(a[j]>a[j+1])
{
temp(a,j,j+1);
}
}
}
System.out.print("最三大数:"+a[7]);
}
/**
* 交换位置
* @author zhengYunfei
* @date 2014-04-16
* @param arr 数组名
* @param a 参数a
* @param b 参数b
*/
public static void temp(int arr[],int a,int b){
int t=arr[a];
arr[a]=arr[b];
arr[b]=t;
}
}
下面就来算算这2个程序运行时间,看看到底哪个效率更高
首先我们定义一个10000个数的一位数组
int a[] = new int[10000];
for(int i=0;i<10000;i++){
a[i]=i;
}
用第一个程序:
package com.yting.hadoop.rpc;
/**
* @title 求一个数组中第三大数是多少
* @author 郑云飞
* @date 2014-04-13
*
*/
public class ArrayDemo2{
public static void main(String[] args){
long pre=System.currentTimeMillis();
int arr[] = new int[10000];
for(int i=0;i<10000;i++){
arr[i]=i;
}
int x=show(arr);
long last=System.currentTimeMillis();
long time=last-pre;
System.out.println("第三大数="+x+"\t"+"耗时:"+time+"毫秒");
}
/**
* @author 郑云飞
* @date 2014-04-13
* @param arr 数组
* @return 第三大数
*/
public static int show(int arr[]){
for(int i=0;i<arr.length-1;i++){
for(int j=i+1;j<arr.length;j++){
if(arr[i]>arr[j]){
temp(arr,i,j);//交换位置
}
}
}
return arr[arr.length-3];
}
/**
* @title 交换位置
* @param arr 数组名
* @param a 参数a
* @param b 参数b
*/
public static void temp(int arr[],int a,int b){
int t=arr[a];
arr[a]=arr[b];
arr[b]=t;
}
}
运行结果如下:
第三大数=9997 耗时:85毫秒
改进后的程序:
package com.yting.hadoop.rpc;
/**
* @title 求一个数组中第三大数是多少
* @author 郑云飞
* @date 2014-04-16
*
*/
public class ArrayDemo {
public static void main(String[] args) {
long pre=System.currentTimeMillis();
int a[] = new int[10000];
for(int i=0;i<10000;i++){
a[i]=i;
}
int i,j;
//用冒泡排序实现升序的过程,只执行三次排查即可,第三大的数会排到倒数第3位的位置
for(i=0;i<3;i++)
{
for(j=0;j<10000-i-1;j++)
{
if(a[j]>a[j+1])
{
temp(a,j,j+1);
}
}
}
long last=System.currentTimeMillis();
long time=last-pre;
System.out.println("10000个数中第三大数是"+a[10000-3]+"\t耗时:"+time+"毫秒");
}
/**
* 交换位置
* @author zhengYunfei
* @date 2014-04-16
* @param arr 数组名
* @param a 参数a
* @param b 参数b
*/
public static void temp(int arr[],int a,int b){
int t=arr[a];
arr[a]=arr[b];
arr[b]=t;
}
}
运行结果如下:
10000个数中第三大数是9997 耗时:1毫秒
再将数组提升到100000个,前者耗时:
第三大数=99997 耗时:13906毫秒
改进后的程序耗时:
100000个数中第三大数是99997 耗时:7毫秒
数组个数越大,2者的差别越明显。
所以执行同样的结果,不同的算法,执行的效率相差真的很大,所以,编程当中优化算法,优化执行效率,才是编程之美。
再次感谢面试官,让我对这个程序进行了更深层次的研究。还希望请您再阅读一下,看看有没有更好的更有效率的算法,尽情期待。
优化后的算法,请看紧跟此博客其后的下一篇博客:深入探究第3大数