參考July博客:最大連續子序列乘積
先考慮不連續的
思路:一維動態規划
考慮到乘積子序列中有正有負也還可能有0,可以把問題簡化成這樣:
- 數組中找一個子序列,使得它的乘積最大;同時找一個子序列,使得它的乘積最小(負數的情況)。
- 雖然只要一個最大積,但由於負數的存在,也要記錄最小乘積。碰到一個新的負數元素時,最小乘積相乘之后得到最大值。
代碼:
1 int maxSuccessiveProduct(int num[], int n) 2 { 3 if(n < 1) 4 return INT_MIN; 5
6 int max_prod = num[0], min_prod = num[0]; 7 int max_res = max_prod; 8
9 for(int i = 1; i < n; ++i) 10 { 11 int cur_prod1 = max_prod * num[i]; 12 int cur_prod2 = min_prod * num[i]; 13
14 max_prod = max(max_prod, max(cur_prod1, cur_prod2)); 15 min_prod = min(min_prod, min(cur_prod1, cur_prod2)); 16
17 max_res = max(max_prod, min_prod); 18 } 19
20 return max_res; 21 }
再考慮連續的
思路:
和不連續的差不多,不過要同時記錄當前子串的最大/最小乘積,如果最大的乘積<當前值,則開始新的子串。
代碼:
1 int maxProduct(int A[], int n) { 2 int maxEnd = A[0]; 3 int minEnd = A[0]; 4 int maxResult = A[0]; 5
6 for (int i = 1; i < n; ++i) 7 { 8 int end1 = maxEnd * A[i], end2 = minEnd * A[i]; 9 maxEnd = max(max(end1, end2), A[i]); //和上面的不同在於,外層max的另一個參數是當前元素值 10 minEnd = min(min(end1, end2), A[i]); 11 maxResult = max(maxResult, maxEnd); 12 } 13 return maxResult; 14 }
