152.乘积最大子数组

70 阅读1分钟

题目:
给你一个整数数组 nums ,请你找出数组中乘积最大的非空连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。

测试用例的答案是一个 32-位 整数。

子数组 是数组的连续子序列。
算法:
方法一:动态规划
dp以i结尾的子数组的最小/大乘积需要保存最大乘积和最小乘积 如[-2,3,-5]

func maxProduct(nums []int) int {
	// dp[i][0],dp[i][1]保存以i结尾的子数组的最小/大乘积
	dp := make([][]int, len(nums))
	dp[0] = []int{nums[0], nums[0]}
	ans := nums[0]
	for i := 1; i < len(nums); i ++ {
		minV, maxV := minMax(dp[i - 1][1] * nums[i], dp[i - 1][0] * nums[i], nums[i])
		dp[i] = []int{minV, maxV}
		if maxV > ans {
			ans = maxV
		}
	}
	// fmt.Println(dp)
	return ans
}

func minMax(a, b, c int) (int, int) {
	min := a
	max := c
	if b < min {
		min = b
	}
	if c < min {
		min = c
	}
	if a > max {
		max = a
	}
	if b > max {
		max = b
	}
	return min, max
}

方法一:动态规划(优化空间)
至于前一个min,max有关,优化空间

  • 188/188 cases passed (4 ms)
  • Your runtime beats 93.5 % of golang submissions
  • Your memory usage beats 44.23 % of golang submissions (3.2 MB)
func maxProduct(nums []int) int {
	minV, maxV := nums[0], nums[0]
	ans := maxV
	for i := 1; i < len(nums); i ++ {
		minV, maxV = minMax(minV * nums[i], maxV * nums[i], nums[i])
		if maxV > ans {
			ans = maxV
		}
	}
	return ans
}

func minMax(a, b, c int) (int, int) {
	min := a
	max := c
	if b < min {
		min = b
	}
	if c < min {
		min = c
	}
	if a > max {
		max = a
	}
	if b > max {
		max = b
	}
	return min, max
}