题目解析
问题理解
题目要求我们从给定的数组中找到一段连续区间的最大乘积,并返回该区间的起始和结束位置。数组中的元素都是2的幂次,因此乘积会迅速增大。我们需要特别注意乘积的计算和比较,以及如何处理0的情况。
思路
-
初始化变量:
max_product:用于存储最大乘积,初始化为一个较小的值(如-1)。start和end:用于存储最大乘积区间的起始和结束位置,初始化为-1。current_product:用于存储当前区间的乘积,初始化为1。current_start:用于存储当前区间的起始位置,初始化为0。
-
遍历数组:
- 使用
for循环遍历数组中的每个元素。 - 如果当前元素是
0,重置current_product和current_start。 - 否则,更新
current_product为当前乘积乘以当前元素。 - 如果
current_product大于max_product,更新max_product和区间start、end。 - 如果
current_product等于max_product,比较区间并更新start和end。
- 使用
-
返回结果:
- 返回区间的起始和结束位置(从1开始计数)。
图解
假设我们有一个数组 [1, 2, 4, 0, 8],我们可以通过以下步骤找到最大乘积区间:
-
初始状态:
max_product = -1start = -1end = -1current_product = 1current_start = 0
-
遍历数组:
- 第1个元素
1:current_product = 1,max_product = 1,start = 0,end = 0 - 第2个元素
2:current_product = 2,max_product = 2,start = 1,end = 1 - 第3个元素
4:current_product = 8,max_product = 8,start = 0,end = 2 - 第4个元素
0:重置current_product = 1,current_start = 4 - 第5个元素
8:current_product = 8,max_product = 8,start = 4,end = 4
- 第1个元素
-
最终结果:
- 最大乘积区间为
[1, 3],返回[1, 3]。
- 最大乘积区间为
代码详解
max_product = -1 # 初始化最大乘积为一个较小的值
start, end = -1, -1 # 初始化最大乘积区间的起始和结束位置
current_product = 1 # 当前区间的乘积
current_start = 0 # 当前区间的起始位置
for i in range(n):
if data[i] == 0:
# 如果遇到0,重置当前乘积和起始位置
current_product = 1
current_start = i + 1
else:
current_product *= data[i] # 更新当前乘积
if current_product > max_product:
# 如果当前乘积大于最大乘积,更新最大乘积和区间
max_product = current_product
start = current_start
end = i
elif current_product == max_product:
# 如果当前乘积等于最大乘积,比较区间
if current_start < start or (current_start == start and i < end):
start = current_start
end = i
return [start + 1, end + 1] # 返回区间的起始和结束位置(从1开始计数)
if __name__ == "__main__":
# Add your test cases here
print(solution(5, [1, 2, 4, 0, 8]) == [1, 3])
print(solution(7, [1, 2, 4, 8, 0, 256, 0]) == [6, 6])
总结
- 时间复杂度:O(n),只需要遍历数组一次。
- 空间复杂度:O(1),只使用了常数个额外的变量。
- 关键点:处理0的情况,更新最大乘积和区间,以及返回结果时注意区间的起始和结束位置是从1开始计数。
感悟
1. 数组操作与遍历
- 遍历数组:通过遍历数组,我们可以逐个处理数组中的元素,这是解决许多数组问题的基本方法。
- 状态维护:在遍历过程中,我们需要维护一些状态变量(如当前乘积、最大乘积、当前区间的起始位置等),以便在遍历过程中进行更新和比较。
2. 特殊情况的处理
- 处理0的情况:0会使得乘积变为0,因此我们需要在遇到0时重置当前乘积和起始位置。这教会我们在处理数组问题时,要特别注意特殊值(如0、负数等)对结果的影响。
3. 区间选择与更新
- 区间选择:题目要求在多个区间乘积相同的情况下,优先选择起始位置更小的区间,如果起始位置相同,则选择结束位置更小的区间。这教会我们在处理区间问题时,如何根据题目要求选择合适的区间。
- 区间更新:在遍历过程中,我们需要不断更新最大乘积及其对应的区间。这教会我们在动态更新过程中,如何保持状态的一致性和正确性。