google笔试题一道

来源:互联网 发布:openwrt挂载网络硬盘 编辑:程序博客网 时间:2024/05/03 07:55
====================================================================

出自: http://www.phpx.com

被其中一道简单的题难住了,大家来说说怎么解?
N个整数,求其中任意N-1个数的乘积中的最大的一个。
例如 3,2,1,则最大的是3*2=6
提示:整数包括0和负数
要求给出个比较有效率的算法

==================================================================== 

以上来自phpx,是原题的引用,下面是求解

收藏,稍后求解

现在正在赶着给一个系统添加功能!

以下是main.cpp的代码,使用dev c++编译通过

 

#include <cstdlib>
#include 
<iostream>
#define m_length 6
/*
传说中的google笔试题一道
N个整数,求其中任意N-1个数的乘积中的最大的一个。
例如 3,2,1,则最大的是3*2=6
提示:整数包括0和负数
要求给出个比较有效率的算法 
*/


/*
目前的分析
首先N个数的乘积分为负与非负两种情况
如果当前结果为负,则扔掉一个负数里面最大的数[绝对值最小]
如果当前结果非负,则扔掉一个非负数里面最小的数[绝对值最小]
如此一来,剩下的N-1个数的成绩一定是非负的结果,并且是最大的非负结果 

程序思路
1.输入N个数,记录负数个数M 
2.降序排列,记录负数起点S
3.解决问题
          当 M为偶 
             扔掉S-1号数字
          当 M为奇
             扔掉S号数字 


4.得到最大积
 
开始编码实现 
*/

using namespace std;

int input(int *num,int n)
{
    
int nNegative(0);
    
for(int i=0;i<n;i++)
    
{
        cout
<<"Input Number ["<<i<<"]:";
        cin
>>num[i];
        
if(num[i]<0)nNegative++;
        }

    cout
<<"Input complete!"<<endl;
    
return nNegative;
    }


int sortint(int *num,int n)
{
    
int temp(0);
    
int j;
    
for (int gap = n/2; gap; gap = gap/2)
    
{
        
for (int i = gap; i < n; i++)
        
{
            temp 
= num[i];
            
for (j = i; j >= gap && temp > num[j - gap]; j -= gap)
            
{
                num[j] 
= num[j - gap];  
            }

            num[j] 
= temp;
        }

    }
 
    
    temp
=0;
    
while(num[temp]>=0)temp++;
    
return temp;
    
}




int main(int argc, char *argv[])
{
    
int num[m_length],N(m_length),M(0),S(0),sum(1);
    
    
//输入数据 
    M=input(num,N);
    
    
//排序 
    S=sortint(num,N);

    cout
<<endl<<"排序后的序列:"<<endl;
    
for(int i=0;i<N;i++)cout<<num[i]<<" ";
    cout
<<endl<<endl;    

    cout
<<"负数个数:"<<M<<endl;
    cout
<<"第一个负数的下标:"<<S<<endl;
    
    
//扔数 
    if(M%2==0)
        S
=S-1;
    cout
<<"扔掉的数组元素:"<<num[S]<<endl; 
    
    
//求积 
    int j(0);
    
for(int i=1;i<N;i++)
    
{
            
while(j==S)j++;
            sum
=sum*num[j];
            j
++;
    }
 
    
    cout
<<"最大积:"<<sum<<endl<<endl;
    
    system(
"PAUSE");
    
return EXIT_SUCCESS;
}

 

还没有经过优化

再考虑考虑,看看有没有优化的方法

似乎并没有这样麻烦啊

从网上搜了搜

看到有位兄弟说的很对

求全部乘积[0不考虑],然后与每个非零数字相除,就可以找到最大的N-1个数的乘积了

现在才发现,这个N与N-1之间的特殊关系

所以,写下了下面的代码,思想并非原创,仅仅是代码实现而已,还要继续学习

 

#include <cstdlib>
#include 
<iostream>
#define m_length 6
using namespace std;

void input(int *num,int n)
    
{
    
int nNegative(0);
    
for(int i=0;i<n;i++)
       
{
        cout
<<"Input Number ["<<i<<"]:";
        cin
>>num[i];
        
if(num[i]<0)nNegative++;
        }

    cout
<<"Input complete!"<<endl;
    }



int main(int argc, char *argv[])
{
    
int num[m_length];
    
long sum(1);
    
int tempSum(0),tempSub(0),tempZero(0),ZeroSub(0);
    
    input(num,m_length);
    
    
for(int i=0;i<m_length;i++)
    
{
        
if(num[i]!=0)sum=sum*num[i];
        
else
        
{
            tempZero
++;
            ZeroSub
=i;
        }
      
    }

    
    
if(tempZero>1)
    
{
        tempSum
=0;
        tempSub
=ZeroSub;
    }

    
else
    
{
        tempSub
=0;
        
if(num[tempSub]!=0) tempSum=sum/num[tempSub];
        
else
        
{
            tempSub
++;
            tempSum
=sum/num[tempSub];
        }

        
        
for(int i=1;i<m_length;i++)
        
{
            
if(num[i]!=0)
            
{
                
if(sum/num[i]>tempSum)
                
{
                    tempSub
=i;
                    tempSum
=sum/num[tempSub];
                }

            }

            
else
            
{
                
if(sum>tempSum)
                
{
                    tempSub
=i;
                    tempSum
=sum;
                    
break;
                }

                
else
                

                    tempSum
=0;
                    
break;
                }

            }

        }

   }

     
    
    cout
<<endl<<"被抛弃的元素下标[如果结果为0,则此下标没有参考价值]:"<<tempSub<<endl;
    cout
<<"最终得到的结果:"<<tempSum<<endl;
    
    
    system(
"PAUSE");
    
return EXIT_SUCCESS;
}

 

不用排序,很简单的逻辑

效率应该是目前来说最高的