長度爲n的整形數組,找出其中的任意n-1個數乘積最大的那一組

問題描述:長度爲n的整形數組,找出其中的任意n-1個數乘積最大的那一組,可以用乘法,但不能用除法,要求對算法處理的 時間複雜度和空間複雜度做出分析。

方法一:

首先能想到的一般方法就是暴力求解法。假設去掉第一個元素,求剩下n-1個乘積賦值給max,同時記錄下下標index;然後假設第二個元素去掉,求剩下n-1個的乘積,若比前一個大則max等於當前值,index更新。重複此過程一直到最後一個元素。最後得到的max就是除去下標爲index的n-1個元素乘積的最大值。

int max=0;
int index=0;
for(int i=0;i<a.length;i++){
    int j=0;
    int muti =1;
    while(true){
     if(j!=i){
        mutil *=a[j];
     }
     j++;
     if(j==a.length)
     break;
   }
   if(max<mutil){
        max =mutil;
        index = i;
     }
}

for(int i=0;i<a.length;i++){
   if(index!=i)
   System.out.print(a[i]+ " ");
}

方法的時間複雜度爲O(n^2),空間複雜度爲O(1)

方法二:

既然事先給定n給整數,那麼其乘積是一定的。不妨設這n個數的乘積爲P,那麼求n-1個數的乘積的最大值只需求P/a[i]的最大值。而題目要求說不能使用除法,那麼轉化思路。P/a[i]=(P*a[i])/a[i]^2,其中a[i]^2一定是正數,可以發現P/a[i]和P*a[i]同正負。現在我們可以把P/a[i]跟P*a[i]聯繫起來。
P的可能取值可能爲正、負和0。

a. P值爲正的情況。
問題轉化求Max(P/a[i]),如果此時有至少一個a[m]爲正值,那麼Max(P/a[i])必定爲正值,所以P*a[i]也必定爲正值i(指數組元素爲正值的下標)。因爲P爲正值,且P*a[i]的值越大表明a[i]的值越大,那麼P/a[i]的值就會越小;P*a[i]的值越小表明a[i]的值越小,那麼P/a[i]的值就會越大。那麼問題轉化爲求P*a[i]的最小正值,即求a[i]的最小正值,剩餘n-1個元素的乘積最大。
如果此時a[i]全爲負值,那麼找出a[i]中最小的那個,剩餘n-1個元素的乘積最大。

  • b.P爲負值的情況
    問題還是求Max(P/a[i]),那麼此時有至少一個a[m]爲負值,那麼Max(P/a[i])必定爲正值,所以P*a[i](i指數組元素爲負值的下標)也必定爲正值。因爲P爲負值,且P*a[i]的值越大表明a[i]的值越小,也就是a[i]的絕對值越大,那麼P/a[i]的值就會越小;P*a[i]的值越小表明a[i]的值越大,a[i]爲負數絕對值越小,那麼P/a[i]的值就會越大。那麼問題轉化爲求P*a[i]的最小正值,此處P爲負值,所以應該求負數集合a[i]中的最大值,對應絕對值最小。

  • c.P爲0的情況
    P爲0 ,意味着數組中存在至少一個0。
    找出爲0 的元素,若大於一個,那麼n-1個元素的最大值乘積爲0此,只要包含0元素的集合均滿足條件,也就是任取n-1個元素(題目是說求一組,應該不會出現這種情況);若只有一個,那麼求出0元素以外的乘積,若該乘積爲負,則n-1個元素的最大乘積爲0,只要包含0的元素集合均滿足條件。若該乘積爲正,則除0元素的外的n-1個滿足條件。

  • 結論:
    n個元素的乘積爲正,且有元素爲正,那麼排除該正整數集中的最小值剩下的n-1個元素即爲所求。若n個元素全爲負,則找負正整數集中的最小值,排除該元素後剩餘的n-1個即爲所求。
    n個元素的乘積爲負,那麼找出該負正整數集中最大的元素,排除該元素後,剩餘的元素即爲所求。
    有一個0元素,求其餘元素的正負;有兩個0元素,任意n-1個元素均滿足條件。

public class FindNum{
      private static    int zero =0;//0元素個數
      private static    int zeroIndex=0;//0元素所在位置
      private static    int positiveCounts =0;//正整數個數
      private static    int negitiveCounts =0;//負整數個數
      private static    int p=1;//標誌N個數的乘積的正負
      private static    int index =0;//待排除元素的下標

  public void init(){
        for(int i=0;i<a.length;i++){
            if(a[i]==0){
                zero++;
                zeroIndex=i;
            }else if(a[i]>0){
                positiveCounts++;
            }else {
               negitiveCounts++;
            }
        }
 }
 //求乘積的正負
  public int getP(int zero ,int negitiveCounts){
         if(zero!=0) return 0;
         if(negitiveCounts%2==0) return 1;
         return -1;
 }   

//flag=1,找正整數集中最小值;flag =-1,找負整數集的最小值;
//flag=0,找負整數集中最大值。
    public int    getIndex(int flag){
         int index=0;
         if(flag>=1){
             int cmp=0;
             for(int i=0;i<a.length;i++){
                 if(a[i]>0&&cmp>a[i]){
                     cmp=a[i];
                     index=i;
                }
           }
      }else if(flag<=-1) {
           int cmp=0;
          for(int i=0;i<a.length;i++){
               if(a[i]<0&&cmp>a[i]){
                   cmp=a[i];
                   index=i;
               }
         }
       } else {
            int cmp=a[0];
           for(int i=0;i<a.length;i++){
                if(a[i]<0&&cmp<a[i]){
                     cmp =a[i];
                    index=i;
              }
         }
      }
    return index;
}     


    //打印
    public void print(int index){
         for(int i=0;i<a.length;i++){
             if(index!=i)
            System.out.print(a[i]+ " ");
       }
    }

public static void main(String [] args){
    FindNum f = new FindNum();
     f.init();
     p=getP(0,negitiveCounts);
     if(zero=1){
          if(p>0)  print(zeroIndex);
          else if(p<0) 包含0的n-1個元素都可以
       } else if(zero>1){
            任意N-1個元素都可以
       } else {
           if(p>0){
                if(positiveCounts>0){
                     index =getIndex(1);//返回正整數集中最小值
               }else {
                    index = getIndex(-1);//返回負整數集中最小值
               }
           }else if(p<0){
                 index = getIndex(0);//返回負整數中的最大值
         }
          print(index); 
     }
} 

該算法的時間複雜度爲O(n),空間複雜度爲O(1)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章