中国电信面试--续集

     首先感谢面试官,看了我的博客,并认真读了我的博客,并针对求第三大数的算法,给出了我宝贵的建议;

对于我来说,这样才有有意,这样学习才能成长,这样进步才能更快;

     首先题目很简单,就是求若干个数中第三个数是多少?我第一次写的程序如下:

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大数

猜你喜欢

转载自zhengyunfei.iteye.com/blog/2047527