Skip to content

Commit 7eac78a

Browse files
committed
#270 Maximum Product Subarray
1 parent e7d423e commit 7eac78a

File tree

1 file changed

+89
-0
lines changed

1 file changed

+89
-0
lines changed
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
# Time Complexity: O(n)
3+
4+
# Space Complexity: O(1)
5+
6+
# Solution
7+
1. array에 0이 존재하는 경우
8+
9+
(observation: 정답이 음수가 될 가능성이 있는가? Yes. 다만, 원소 개수가 1개이고, 그 원소가 음수인 경우에만 그렇다. 음수인 원소가 2개 이상인 경우는 subarray를 잘 선택하면 그 곱을 항상 0 이상으로 만들 수 있다. 즉, 원소 개수가 1개이고 음수인 경우만 예외 처리를 해주면, 그 외의 경우는 정답이 0이거나 양수이다.)
10+
11+
subarray에 0이 포함되는 순간 곱은 0이 되므로, 0보다 큰 곱을 찾기 위해서는 0을 제외하고 판단한다.
12+
즉, 0을 기준으로 slice해서, 각각의 segment만 독립적으로 검토하면 된다. (0으로 slice한 각 segment가 아래 2번 케이스로 환원된다.)
13+
14+
2. (sub)array에 0이 존재하지 않는 경우
15+
음수의 개수에 따라 접근을 다르게 한다.
16+
17+
2-1. 짝수개
18+
고민할 것 없이, 전체 subarray의 원소를 곱하면 그 subarray에서 얻을 수 있는 곱의 최대값이다.
19+
20+
2-2. 홀수개
21+
subarray 양 끝에서 각각 출발하여 최초의 마이너스(즉 가장 바깥쪽의 마이너스)를 만날 때까지, 원소들을 누적해서 곱하며 이동.
22+
두 값 중 절대값이 작은 쪽을 subarray에서 제외. 남은 부분의 곱을 구하면, 최대값이다.
23+
*/
24+
25+
class Solution {
26+
public int maxProduct(int[] nums) {
27+
if (nums.length == 1) {
28+
return nums[0];
29+
}
30+
31+
int ans = 0;
32+
int start = 0;
33+
for (int i = 0; i < nums.length; i++) {
34+
if (nums[i] != 0) {
35+
continue;
36+
}
37+
38+
if (i > 0) {
39+
int res = calculateMaxProduct(start, i - 1, nums);
40+
ans = Math.max(ans, res);
41+
}
42+
start = i + 1;
43+
}
44+
45+
if (start <= nums.length - 1) {
46+
int res = calculateMaxProduct(start, nums.length - 1, nums);
47+
ans = Math.max(ans, res);
48+
}
49+
50+
return ans;
51+
}
52+
53+
private int calculateMaxProduct(int l, int r, int[] nums) {
54+
if (l == r) {
55+
return nums[l];
56+
}
57+
58+
int minusCount = 0;
59+
int product = 1;
60+
for (int i = l; i <= r; i++) {
61+
if (nums[i] < 0) {
62+
minusCount++;
63+
}
64+
product *= nums[i];
65+
}
66+
67+
if (minusCount % 2 == 0) {
68+
return product;
69+
} else {
70+
int leftProduct = 1;
71+
for (int i = l; i <= r; i++) {
72+
leftProduct *= nums[i];
73+
if (nums[i] < 0) {
74+
break;
75+
}
76+
}
77+
78+
int rightProduct = 1;
79+
for (int i = r; i >= l; i--) {
80+
rightProduct *= nums[i];
81+
if (nums[i] < 0) {
82+
break;
83+
}
84+
}
85+
86+
return product / Math.max(leftProduct, rightProduct);
87+
}
88+
}
89+
}

0 commit comments

Comments
 (0)