[LeetCode#152] Maximum Product Subarray

2025. 1. 16. 11:39·Algorithm/문제풀이

 

❐ Description


문제 링크 https://leetcode.com/problems/maximum-product-subarray/description/
난이도 Medium

 

 

 

 

 

 

❐ 문제 분석


이 문제는 배열 내 음수, 0, 양수의 특성을 고려해야 하기 때문에 단순히 한 번의 반복으로 최대값을

찾을 수 없다. 대신 DP를 사용하여 최대값과 최소값을 동시에 추적하여 풀이해야 한다.

 

그럼 왜 최소값도 추적해야 할까? 음수가 곱해질 경우, 최소값이 최대값으로 변할 수 있기 때문이다.

예를들어, `[-2, 3, -4]`에서는

  • `-2`를 시작으로 음수를 만나면 곱셈 결과가 양수가 된다.
  • 따라서 현재 최소값을 함께 고려해야 최대값을 얻을 수 있다.

 

 

 

 

 

❐ 문제 풀이


1. Dynamic Programming

public class SolutionV1 {
    public int maxProduct(int[] nums) {
        if (nums == null || nums.length == 0) return 0;

        // 초기값 설정
        int maxProduct = nums[0];
        int minProduct = nums[0];
        int result = nums[0];

        // 배열 순회
        for (int i = 1; i < nums.length; i++) {
            int num = nums[i];

            // 음수를 만나면 max와 min을 스왑
            if (num < 0) {
                int temp = maxProduct;
                maxProduct = minProduct;
                minProduct = temp;
            }

            // 현재 숫자를 포함한 최대/최소값 갱신
            maxProduct = Math.max(num, maxProduct * num);
            minProduct = Math.min(num, minProduct * num);

            // 최대값 갱신
            result = Math.max(result, maxProduct);
        }

        return result;
    }

    public static void main(String[] args) {
        int[] nums = {-3, 0, 1, -2};

        SolutionV1 solution = new SolutionV1();
        int answer = solution.maxProduct(nums);
        System.out.println(answer);
    }
}

 

 

2. Two Pointer

public class SolutionV2 {
    public int maxProduct(int[] nums) {
        int n = nums.length;
        int left = 1, right = 1;
        int ans = nums[0];

        for (int i = 0; i < n; i++) {

            //if any of l or r become 0 then update it to 1
            left = left == 0 ? 1 : left;
            right = right == 0 ? 1 : right;

            left *= nums[i];   //prefix product
            right *= nums[n - 1 - i];    //suffix product

            ans = Math.max(ans, Math.max(left, right));

        }

        return ans;
    }

    public static void main(String[] args) {
        int[] nums = {-3, 0, 1, -2};

        SolutionV2 solution = new SolutionV2();
        int answer = solution.maxProduct(nums);
        System.out.println(answer);
    }
}

이 방식의 핵심은 left 또는 right의 값이 0이 될 때 이를 1로 치환하는 것이다.

이렇게 되면 배열 중간에 0이 있는 경우도 대응할 수 있다.

 

위 코드의 동작 방식은 아래와 같다. (leetcode solution paper)

int[] nums = {-3, 0, 1, -2};

// i = 0 / left = 1 / right = 1 / ans = -3
int left = 1 * -3 = -3;
int right = -2 * 1 = -2;
int ans = Math.max(-3, -2) = -2;

// i = 1 / left = -3 / right = -2 / ans = -2
int left = -3 * 0 = 0;
int right = -2 * 1 = -2;
int ans = Math.max(0, -2) = 0;

// i = 2 / left = 0 / right = -2 / ans = 0
int left = 1(left가 0이라면 1로 치환) * 1 = 1; 
int right = -2 * 0 = 0;
int ans = Math.max(0, 1) = 1;

// i = 3 / left = 1 / right = 0 / ans = 1
int left = 1 * -2 = -2;
int right = 1 * -3 = -3;
int ans = Math.max(1, -2) = 1;

 

 

 

 

 


'Algorithm > 문제풀이' 카테고리의 다른 글

[LeetCode#15] 3Sum  (0) 2025.01.21
[LeetCode#300] Longest Increasing Subsequence  (0) 2025.01.15
[LeetCode#151] Reverse Words in a String  (0) 2025.01.13
[LeetCode#198] House Robber  (0) 2025.01.09
[LeetCode#128] Longest Consecutive Sequence  (0) 2025.01.07
'Algorithm/문제풀이' 카테고리의 다른 글
  • [LeetCode#15] 3Sum
  • [LeetCode#300] Longest Increasing Subsequence
  • [LeetCode#151] Reverse Words in a String
  • [LeetCode#198] House Robber
gilbert9172
gilbert9172
gilbert9172 님의 블로그 입니다.
  • gilbert9172
    バックエンド
    gilbert9172
  • 전체
    오늘
    어제
    • All Categories (207)
      • 우테코 7기 (21)
        • 1주차 (8)
        • 2주차 (5)
        • 3주차 (6)
      • Langauge (6)
        • Java (3)
        • Kotlin (3)
      • Back-End (13)
        • SpringBoot (1)
        • Trouble Shooting (0)
        • Setup & Configuration (1)
        • SQL (3)
        • Redis (8)
      • Architecture (6)
        • Multi Module (1)
        • DDD (5)
      • CS (30)
        • Data Structure (6)
        • Operating System (0)
        • Network (12)
        • Database (10)
        • Design Pattern (2)
      • Algorithm (78)
        • 내용 정리 (18)
        • 문제풀이 (60)
      • DevOps (6)
        • AWS (5)
        • Git (1)
      • Front-End (1)
        • Trouble Shooting (1)
      • Project (6)
        • 페이스콕 (6)
      • Book (39)
        • 친절한 SQL 튜닝 (9)
        • 데이터 중심 애플리케이션 설계 (14)
        • 이벤트 기반 마이크로서비스 구축 (6)
        • Spring Batch docs (10)
        • Quartz docs (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    오블완
    sliding-window
    Back-Tracking
    binarysearch
    Two-Pointer
    greedy
    부분단조성
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
gilbert9172
[LeetCode#152] Maximum Product Subarray
상단으로

티스토리툴바