# 152. Maximum Product Subarray (1)

[Link](https://leetcode.com/problems/maximum-product-subarray/)

Given an integer array `nums`, find the contiguous subarray within an array (containing at least one number) which has the largest product.

**Example 1:**

```
Input: [2,3,-2,4]
Output: 6
Explanation: [2,3] has the largest product 6.
```

**Example 2:**

```
Input: [-2,0,-1]
Output: 0
Explanation: The result cannot be 2, because [-2,-1] is not a subarray.
```

**Solution**

這題的背後思想仍是DP，取最優解(最短路徑，最大(小)值)通常都可用DP\
但我想不到設計DP array的方式:

max\[i] => 結尾在i的最大乘積數\
min\[i] =>結尾在i的最小乘積數

```
    public int maxProduct(int[] nums) {
       int len = nums.length;
        if (len == 0)
            return 0;
        int maxValue = nums[0];
        int[] max = new int[len];
        max[0] = nums[0];
        int[] min = new int[len];
        min[0] = nums[0];
        for (int i = 1; i < nums.length; i++) {
            max[i] = Math.max(nums[i], Math.max(max[i - 1] * nums[i], min[i - 1] * nums[i]));
            min[i] = Math.min(nums[i], Math.min(max[i - 1] * nums[i], min[i - 1] * nums[i]));
            maxValue = Math.max(maxValue, max[i]);
        }
        return maxValue;
    }
```

經過優化後，因為發現max, min不太需要array&#x20;

```
class Solution {
    public int maxProduct(int[] nums) {
        int len = nums.length;
        if(len == 0){
            return 0;
        }
        if(len == 1){
            return nums[0];
        }
        int currentMax = nums[0];
        int currentMin = nums[0];
        int result = currentMax;
        
        for(int i = 1; i < len ; i++){
            //We all have two options when we decide currentMax/currentMin
            //with previousMax (currentMax * nums[i])
            //or not without it (nums[i])
            if(nums[i] >= 0){
                currentMax = Math.max(nums[i], currentMax * nums[i]);
                currentMin = Math.min(nums[i], currentMin * nums[i]);
            }else{
                //means the nums[i] is negative
                //so the currentMax shall more likely appear in currentMin * nums[i]
                int tempMax = currentMax;
                currentMax = Math.max(nums[i], currentMin * nums[i]);
                currentMin = Math.min(nums[i], tempMax * nums[i]);
            }
            
            result = Math.max(result, currentMax);
        }
        return result;
        
    }
}
```
