/*
1. 문제 이해
배열이 주어지고 배열 내의 최대곱이 되는 subarray 를 찾아서 최대값을 반환

답변 참고

이 문제의 핵심은 현재 인덱스에서 음수가 되는 최소 값이 나중에 음수를 만나면 양수가 되어 최대값이 될 수 있으므로
이 상태들을 어떻게 관리할 것인가와 이 개념들을 어떻게 코드로 구현할것인가에 대한 것이 포인트였다.

2. 알고리즘
이전에 longest repeating replacement 문제가 생각났다. 여기서 슬라이딩 윈도우를 사용하였는데
두개의 포인터를 사용해서 슬라이드 내에 값이 조건을 만족하는지 계속 판단하는 방식이었다.
여기도 비슷하게 적용해볼 수 있지 않을까 ?

그럼 각 start와 end 포인터가 언제 움직여야 하는지에 대해 조건을 생각해보자
위 생각은 잘못된 접근이었다.

답변 참고

다이나믹 프로그래밍을 사용해야 한다.
최대곱을 구하기 위해서는 이전 연산에 대한 저장을 해야하기 때문이다.

3. 예외

0일때 ? 

4. 구현

답변 참고
각 인덱스 마다 최대곱, 최소곱을 구해야 하며
후보 1, 2, 3 중 선정해야 한다
왜냐하면 음수가 있기 때문에 음수 * 음수는 양수로 바뀌어 다시 최대값이 될 수 있으므로
가장 적은 최소값을 계속해서 유지해야한다.

후보 1, 2, 3 은
1: 이전 위치의 최소곱 * 현재 위치에 있는 숫자
2: 이전 위치의 최대곱 * 현재 위치에 있는 숫자
3: 현재 위치에 있는 숫자 (부분 배열로 시작)
이 된다
그리고 이때 최대곱의 결과와 이전까지의 최대값을 비교하여 최대값을 갱신해야한다.

최대값, 최소값 초기화
for문 시작
후보1
후보2
후보3

중 최소값과 최대값 세팅
현재 최대값과 기존의 최대값중 더 큰 값으로 최대값 초기화

for문 종료

최대값 반환

*/

import java.util.*;

class Solution {
    public int maxProduct(int[] nums) {
        int max = 1;
        int min = 1;
        int fir, sec, thr;
        int maxResult = Integer.MIN_VALUE;
        

        for (int i : nums) {
            fir = min * i;
            sec = max * i;
            thr = i;
            max = Math.max(fir, Math.max(sec, thr));
            min = Math.min(fir, Math.min(sec, thr));
            maxResult = Math.max(maxResult, max);
        }

        return maxResult;
        
    }
}

