@@ -7,14 +7,18 @@ import kotlin.math.min
7
7
8
8
class `maximum- product- subarray` {
9
9
10
+ fun maxProduct (nums : IntArray ): Int {
11
+ return usingOptimizedDP(nums)
12
+ }
13
+
10
14
/* *
11
15
* 현재의 값, 이전 위치의 최대 누적곱, 이전 위치의 최소 누적곱 이 세 개를 비교하여 한 번의 순회로 최대 값을 반환한다.
12
16
* 음수와 음수가 곱해져 최대 값이 도출될 수 있기에 DP 배열을 두 개 생성한다.
13
17
* TC: O(n), SC: O(n)
14
18
*/
15
- fun maxProduct (nums : IntArray ): Int {
19
+ private fun usingDP (nums : IntArray ): Int {
16
20
val (min, max) = IntArray (nums.size) { 11 }.apply { this [0 ] = nums[0 ] } to IntArray (nums.size) { - 11 }.apply { this [0 ] = nums[0 ] }
17
- var result = max( - 11 , nums[0 ])
21
+ var result = nums[0 ]
18
22
for (index in 1 until nums.size) {
19
23
max[index] = max(max(nums[index], nums[index] * max[index - 1 ]), nums[index] * min[index - 1 ])
20
24
min[index] = min(min(nums[index], nums[index] * max[index - 1 ]), nums[index] * min[index - 1 ])
@@ -24,11 +28,29 @@ class `maximum-product-subarray` {
24
28
return result
25
29
}
26
30
31
+ /* *
32
+ * DP 배열이 입력받는 정수의 배열만큼 생성할 필요가 없고, 이전 값과 현재 값만 기억하면 되므로 공간복잡도가 개선되었다.
33
+ * TC: O(n), SC: O(1)
34
+ */
35
+ private fun usingOptimizedDP (nums : IntArray ): Int {
36
+ var (min, max) = nums[0 ] to nums[0 ]
37
+ var result = nums[0 ]
38
+ for (index in 1 until nums.size) {
39
+ val (tmpMin, tmpMax) = min to max
40
+ max = max(max(nums[index], nums[index] * tmpMax), nums[index] * tmpMin)
41
+ min = min(min(nums[index], nums[index] * tmpMax), nums[index] * tmpMin)
42
+ result = max(max(min, max), result)
43
+ }
44
+
45
+ return result
46
+ }
47
+
27
48
@Test
28
49
fun `입력받은 정수 배열의 가장 큰 곱을 반환한다` () {
29
50
maxProduct(intArrayOf(2 ,3 ,- 2 ,4 )) shouldBe 6
30
51
maxProduct(intArrayOf(- 2 ,0 ,- 1 )) shouldBe 0
31
52
maxProduct(intArrayOf(- 10 )) shouldBe - 10
32
53
maxProduct(intArrayOf(- 2 ,3 ,- 4 )) shouldBe 24
54
+ maxProduct(intArrayOf(- 4 ,- 3 ,- 2 )) shouldBe 12
33
55
}
34
56
}
0 commit comments