每日一题:查找数组中最大最小值

每日一题:查找数组中最大最小值


 

问题描述:

给定数组a1, a2,  a3, ... an,要求编写函数f输出改数组的最大值和最小值。假设数组中的值两两不相同。


 

思路:

朴素的算法可以通过遍历的算法,通过2n次的比较得到数组中的最大值和最小值。实现代码如下:

   public   class  Pair
    {
        
//  构造函数
         public  Pair( int  max,  int  min)
        {
            
this ._max  =  max;
            
this ._min  =  min;
        }

        
//  属性
         private   int  _max;
        
public   int  Max
        {
            
get  
            {
                
return   this ._max;
            }
            
set
            {
                
this ._max  =  value;
            }
        }

        
private   int  _min;
        
public   int  Min
        {
            
get
            {
                
return   this ._min;
            }
            
set
            {
                
this ._min  =  value;
            }
        }
    }

    
public   class  SearchMinAndMax
    {
        
private   int [] arr  =   { 2 3 1 5 6 ,   9 7 8 };

        
public  Pair function1() 
        {
            
//  初始化
             int  max, min;
            
if  ( this .arr[ 0 <   this .arr[ 1 ])
            {
                max 
=   this .arr[ 1 ];
                min 
=   this .arr[ 0 ];
            }
            
else
            {
                max 
=   this .arr[ 0 ];
                min 
=   this .arr[ 1 ];
            }

            
//  开始循环查找
             for  ( int  i  =   2 ; i  <   this .arr.Length;  ++ i )
            {
                
//  比min还小
                 if ( this .arr[i]  <  min)
                {
                    min 
=   this .arr[i];
                }

                 
//  比max还大
                 if ( this .arr[i]  >  max)
                {
                    max 
=   this .arr[i];
                }

            }

            
//  循环结束,返回结果
             return   new  Pair(max, min);
        }
    }

下面的过程将是不断修正上面算法的过程。考虑这个算法:将数组逻辑上分为两个两个为一组,然后比较每组中两个值的大小,如果比max还大,修改max的值,同理对min,通过这种算法的修正的话,需要的比较次数如下:1.5n。改算法实现起来主要是需要判定数组长度的奇偶性。代码如下:

public  Pair function2()
        {
            
//  这里使用的分组的方式 

            
//  计算分组数 
             int  n  =   this .arr.Length  /   2 ;     //  取整运算

            
//  使用第一个分组初始化max和min
             int  max, min;
            
if  ( this .arr[ 0 <   this .arr[ 1 ])
            {
                max 
=   this .arr[ 1 ];
                min 
=   this .arr[ 0 ];
            }
            
else
            {
                max 
=   this .arr[ 0 ];
                min 
=   this .arr[ 1 ];
            }

            
//  遍历分组数
             int  tmpMax  =   int .MaxValue, tmpMin  =   int .MinValue;
            
for  ( int  i  =   2 ; i  <=  n;  ++ i)
            {
                
//  得到每个分组中的最大值和最小值,一次比较
                 if ( this .arr[ 2   *  i  -   2 >   this .arr[ 2   *  i  -   1 ])
                {
                    tmpMax 
=   this .arr[ 2   *  i  -   2 ];
                    tmpMin 
=   this .arr[ 2   *  i  -   1 ];
                }
                
else
                 {
                     tmpMin 
=   this .arr[ 2   *  i  -   2 ];
                     tmpMax 
=   this .arr[ 2   *  i  -   1 ];
                 }

                
//  更新整个数组中的最大值和最小值

                
//  第二次比较
                 if  (tmpMax  >  max)
                {
                    max 
=  tmpMax;
                }

                
//  第三次比较
                 if (tmpMin  <  min)
                {
                    min 
=  tmpMin;
                }

            }

            
//  是否存在剩下的元素
             if  ( 2   *  n  <   this .arr.Length)
            {
                
//  还剩下一个元素
                 if  ( this .arr[ 2 *  n]  >  max)
                {
                    max 
=   this .arr[ 2   *  n];
                }

                
if ( this .arr[ 2   *  n]  <  min)
                {
                    min 
=   this .arr[ 2   *  n];
                }
            }

            
//  返回值
             return   new  Pair(max, min);
        }

下面继续优化上面的算法。使用分治思想。实现代码:

  //  begin, end实现闭区间
         public  Pair function3( int  begin,  int  end)
        {
            
//  递归的出口条件
             if (begin  +   1    >=  end)
            {
                
//  如果是奇数个元素,这个可能存在是同一个元素
                 if  ( this .arr[begin]  >=   this .arr[end])
                    
return   new  Pair( this .arr[begin],  this .arr[end]);
                
else
                    
return   new  Pair( this .arr[end],  this .arr[begin]);
            }

            
//  没有达到出口条件,开始递归
             int  middle  =  (end  +  begin  +   1 /   2
            Pair left 
=   this .function3(begin, middle  -   1 );
            Pair right 
=   this .function3(middle, end);

            
//  返回值
             int  max  =   int .MinValue, min  =   int .MinValue;
            
if (left.Max  > right.Max)
            {
                max 
=  left.Max;
            }
            
else
            {
                max 
=  right.Max;
            }

            
if (left.Min  <  right.Min)
            {
                min 
=  left.Min;
            }
            
else
            {
                min 
=  right.Min;
            }

            
return   new  Pair(max, min);
        }

        
public  Pair function3Wrapper()
        {
            
return   this .function3( 0 this .arr.Length  -   1 );
        }


 

转载于:https://www.cnblogs.com/xuqiang/archive/2010/12/07/1953368.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值