题目链接:
题目描述:
思路:
这里的子数组都是连续的元素,可以是元素本身
正常思路,设
i
i
i对应的最大子数组是
d
p
(
i
)
dp(i)
dp(i),则:
d
p
(
i
)
=
m
a
x
{
d
p
(
i
−
1
)
∗
n
u
m
s
[
i
]
,
n
u
m
s
[
i
]
}
dp(i) =max\{ dp(i-1)* nums[i] , nums[i] \}
dp(i)=max{dp(i−1)∗nums[i],nums[i]}
但是,用上面的公式是错误的,因为存在负数,会把最大的变成最小的,反之亦然。
也就是说, i − 1 i-1 i−1对应的最大乘积不一定是 i i i对应的最大乘积,如【0 -2 -3】,对于-2,最大乘积是0,对于-3,最大乘积是6,用上面的公式就是错误的
所以,我们除了记住最大乘积max,也要记住最小乘积min,因为下个元素可能会使最大最小发生转换
设
i
i
i对应的最大子数组是
d
p
m
a
x
(
i
)
dp_{max}(i)
dpmax(i),则:
d
p
m
a
x
(
i
)
=
m
a
x
{
d
p
(
i
−
1
)
m
a
x
∗
n
u
m
s
[
i
]
,
n
u
m
s
[
i
]
,
d
p
(
i
−
1
)
m
i
n
∗
n
u
m
s
[
i
]
}
d
p
m
i
n
(
i
)
=
m
i
n
{
d
p
(
i
−
1
)
m
a
x
∗
n
u
m
s
[
i
]
,
n
u
m
s
[
i
]
,
d
p
(
i
−
1
)
m
i
n
∗
n
u
m
s
[
i
]
}
dp_{max}(i) =max\{ dp(i-1)_{max}* nums[i] , nums[i], dp(i-1)_{min}* nums[i] \} \\ dp_{min}(i) =min\{ dp(i-1)_{max}* nums[i] , nums[i], dp(i-1)_{min}* nums[i] \}
dpmax(i)=max{dp(i−1)max∗nums[i],nums[i],dp(i−1)min∗nums[i]}dpmin(i)=min{dp(i−1)max∗nums[i],nums[i],dp(i−1)min∗nums[i]}
可以看出这里 i i i只和 i − 1 i-1 i−1位置有关,所以不需要数组,用两个数分别代表 i i i和 i − 1 i-1 i−1位置的状态就行
实现代码:
class Solution {
public int maxProduct(int[] nums) {
long max = nums[0] , min = nums[0] ,ans = nums[0];
for(int i = 1; i < nums.length; i++){
long mx = max, mn = min;
max = Math.max(mx * nums[i], Math.max(nums[i], mn * nums[i]));
min = Math.min(mx * nums[i], Math.min(nums[i], mn * nums[i]));
ans = Math.max(ans,max);
}
return (int)ans;
}
}