首先感谢面试官,看了我的博客,并认真读了我的博客,并针对求第三大数的算法,给出了我宝贵的建议;
对于我来说,这样才有有意,这样学习才能成长,这样进步才能更快;
首先题目很简单,就是求若干个数中第三个数是多少?我第一次写的程序如下:
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大数