@@ -7,14 +7,18 @@ import kotlin.math.min
77
88class `maximum- product- subarray` {
99
10+ fun maxProduct (nums : IntArray ): Int {
11+ return usingOptimizedDP(nums)
12+ }
13+
1014 /* *
1115 * 현재의 값, 이전 위치의 최대 누적곱, 이전 위치의 최소 누적곱 이 세 개를 비교하여 한 번의 순회로 최대 값을 반환한다.
1216 * 음수와 음수가 곱해져 최대 값이 도출될 수 있기에 DP 배열을 두 개 생성한다.
1317 * TC: O(n), SC: O(n)
1418 */
15- fun maxProduct (nums : IntArray ): Int {
19+ private fun usingDP (nums : IntArray ): Int {
1620 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 ]
1822 for (index in 1 until nums.size) {
1923 max[index] = max(max(nums[index], nums[index] * max[index - 1 ]), nums[index] * min[index - 1 ])
2024 min[index] = min(min(nums[index], nums[index] * max[index - 1 ]), nums[index] * min[index - 1 ])
@@ -24,11 +28,29 @@ class `maximum-product-subarray` {
2428 return result
2529 }
2630
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+
2748 @Test
2849 fun `입력받은 정수 배열의 가장 큰 곱을 반환한다` () {
2950 maxProduct(intArrayOf(2 ,3 ,- 2 ,4 )) shouldBe 6
3051 maxProduct(intArrayOf(- 2 ,0 ,- 1 )) shouldBe 0
3152 maxProduct(intArrayOf(- 10 )) shouldBe - 10
3253 maxProduct(intArrayOf(- 2 ,3 ,- 4 )) shouldBe 24
54+ maxProduct(intArrayOf(- 4 ,- 3 ,- 2 )) shouldBe 12
3355 }
3456}
0 commit comments