《程式設計之美》 2.13
問題:給定乙個長度為n的整數陣列,只允許用乘法,不能用除法,計算(n-1)個數的組合乘積中最大的一組,並寫出演算法的時間複雜度。
解法一:把所有n-1個數的組合找出來,分別計算乘積,比較大小。o(n^2)。
int maxsubproducti(int a,int n)
for(j = i + 1; j < n; j++)
if (i == 0) ret = prod;
if (prod > ret) ret = prod;
} return ret;
}int maxsubproductii(int a,int n)
if (i == 0) ret = prod;
if (prod > ret) ret = prod;
} return ret;
}
解法二:利用兩個陣列s和s分別表示從陣列a的兩端開始計算的乘積,s[i] = a[0]*a[1]*...*a[i-1],t[j] = a[j]*...*a[n-1]。那麼p[i] = s[i-1] * t[i+1]。時間複雜度為o(n)。
int maxsubproductiii(int a,int n)
maxprod = (s[n-2] > t[1]) ? s[n-2] : t[1];
for(i = 1; i < n - 1; i ++)
free(s);
free(t);
return maxprod;
}
解法三:統計陣列中正數、負數和零的個數,記錄最小的正數、負數以及最大的負數。
1,如果零的個數n_zero大於1,那麼最大乘積為0;
2,如果零的個數n_zero為1:
(1),如果負數的個數n_neg為奇數,那麼最大乘積為0;
(2),如果負數的個數n_neg為偶數,那麼最大乘積計算式扣除a[zeroi];
3,如果零的個數n_zero為0:
(1),如果負數的個數n_neg為奇數,那麼最大乘積計算式扣除a[maxnegi];
(2),如果負數的個數n_neg為偶數:
1> 如果正數的個數n_pos為零,那麼最大乘積計算式扣除a[minnegi];
2> 如果正數的個數n_pos大於零,那麼最大乘積計算式扣除a[minposi];
int maxsubproductiv(int *a, int n)
else if(maxneg < a[i])
if (minneg == 0)
else if (minneg > a[i])
} else if(a[i] == 0) // a[i] is zero
else // a[i] is positive
else if(minpos > a[i])
} }
if((n_zero == 1) && (n_neg & 0x1))
else if((n_zero == 1) && !(n_neg & 0x1))
else if((n_zero == 0) && (n_neg & 0x1))
else if((n_zero == 0) && !(n_neg & 0x1))
else }
for(int i = 0; i < n; i++)
return max;
}int maxsubproductv(int *a, int n)
else if(maxneg < a[i])
if (minneg == 0)
else
} } else if(a[i] == 0) // a[i] is zero
else // a[i] is positive
else if(minpos > a[i])
} }
if (n_zero)
else
else
} for(int i = 0; i < n; i++)
return max;
}
測試程式:
#include #include #include #include int maxsubproducti(int a,int n)
for(j = i + 1; j < n; j++)
if (i == 0) ret = prod;
if (prod > ret) ret = prod;
} return ret;
}int maxsubproductii(int a,int n)
if (i == 0) ret = prod;
if (prod > ret) ret = prod;
} return ret;
}int maxsubproductiii(int a,int n)
maxprod = (s[n-2] > t[1]) ? s[n-2] : t[1];
for(i = 1; i < n - 1; i ++)
free(s);
free(t);
return maxprod;
}int maxsubproductiv(int *a, int n)
else if(maxneg < a[i])
if (minneg == 0)
else if (minneg > a[i])
} else if(a[i] == 0) // a[i] is zero
else // a[i] is positive
else if(minpos > a[i])
} }
if((n_zero == 1) && (n_neg & 0x1))
else if((n_zero == 1) && !(n_neg & 0x1))
else if((n_zero == 0) && (n_neg & 0x1))
else if((n_zero == 0) && !(n_neg & 0x1))
else }
for(int i = 0; i < n; i++)
return max;
}int maxsubproductv(int *a, int n)
else if(maxneg < a[i])
if (minneg == 0)
else
} } else if(a[i] == 0) // a[i] is zero
else // a[i] is positive
else if(minpos > a[i])
} }
if (n_zero)
else
else
} for(int i = 0; i < n; i++)
return max;
}void show(int a,int n)
printf("\n");
}int main()
show(a,n);
printf("max sub product of n-1 elements: %d .\n",maxsubproducti(a,n));
printf("max sub product of n-1 elements: %d .\n",maxsubproductii(a,n));
printf("max sub product of n-1 elements: %d .\n",maxsubproductiii(a,n));
printf("max sub product of n-1 elements: %d .\n",maxsubproductiv(a,n));
printf("max sub product of n-1 elements: %d .\n",maxsubproductv(a,n));
}
測試輸出:
2 -5 -5 -5 -7 2
max sub product of n-1 elements: 1750 .
max sub product of n-1 elements: 1750 .
max sub product of n-1 elements: 1750 .
no zero and even negatives
max sub product of n-1 elements: 1750 .
no zero.
max sub product of n-1 elements: 1750 .
ref:
1,程式設計之美 2.13
最大乘積子陣列
程式設計之美 上有一道關於在長度為n的陣列中找到n 1個元素乘積最大的題目,不過這並不是本文要討論的。本文討論的是另一種情況,給定乙個長度為n的浮點陣列,找乙個長度任意的子陣列 子陣列的元素在原陣列中是連續存放的 這個子陣列的乘積最大。通常,找乙個滿足指定條件子陣列都會使用動態規劃。遞迴縮小問題規模...
子陣列最大乘積
給定乙個double型別的陣列arr,其中的元素可正可負可0,返回子陣列累乘的最大乘積。例如arr 2.5,4,0,3,0.5,8,1 子陣列 3,0.5,8 累乘可以獲得最大的乘積12,所以返回12。解析 此題可以運用動態規劃解決 設f i 表示以i為結尾的最大值,g i 表示以i結尾的最小值,那...
子陣列最大乘積
給定乙個double型別的陣列arr,其中的元素可正可負可0,返回子陣列累乘的最大乘積。例如arr 2.5,4,0,3,0.5,8,1 子陣列 3,0.5,8 累乘可以獲得最大的乘積12,所以返回12。分析 設f i 表示以i為結尾的最大值,g i 表示以i結尾的最小值,那麼 f i 1 的最大值與...