问题描述
小R手上有一个长度为 n
的数组 (n > 0
),数组中的元素分别来自集合 [0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
。小R想从这个数组中选取一段连续的区间,得到可能的最大乘积。
你需要帮助小R找到最大乘积的区间,并输出这个区间的起始位置 x
和结束位置 y
(x ≤ y
)。如果存在多个区间乘积相同的情况,优先选择 x
更小的区间;如果 x
相同,选择 y
更小的区间。
注意:数组的起始位置为 1
,结束位置为 n
。
测试样例
样例1:
输入:
n = 5, arr = [1, 2, 4, 0, 8]
输出:[1, 3]
样例2:
输入:
n = 7, arr = [1, 2, 4, 8, 0, 256, 0]
输出:[6, 6]
样例3:
输入:
n = 8, arr = [1, 2, 4, 8, 0, 256, 512, 0]
输出:[6, 7]
解题思路
- 理解问题:首先,我们需要理解题目要求:找到数组中一段连续区间的最大乘积,并返回该区间的起始和结束位置。我们需要找到数组中一段连续区间的最大乘积。由于数组中的元素都是正数或0,乘积的结果可能会非常大,因此我们需要考虑如何处理这些情况。
- 数据结构选择:我们可以使用两个指针来表示当前考虑的区间,并使用一个变量来记录当前区间的乘积。
- 算法步骤:
- 初始化两个指针
start
和end
,以及一个变量max_product
来记录最大乘积。 - 遍历数组,计算从
start
到end
的乘积。 - 如果乘积为0,则跳过这个区间,并将
start
移动到end
的下一个位置。 - 如果乘积大于
max_product
,则更新max_product
和区间的起始和结束位置。 - 如果乘积等于
max_product
,则比较当前区间的起始和结束位置,选择更小的区间。
- 初始化两个指针
Python3代码(通过Marscode测试)
def solution(n, data):
max_product = 0
best_start = -1
best_end = -1
# 遍历数组,尝试所有可能的区间
for start in range(n):
current_product = 1
for end in range(start, n):
# 计算当前区间的乘积
current_product *= data[end]
# 如果乘积为0,跳过这个区间
if current_product == 0:
break
# 如果当前乘积大于最大乘积,更新最大乘积和区间
if current_product > max_product:
max_product = current_product
best_start = start
best_end = end
# 如果乘积相等,选择更小的区间
elif current_product == max_product:
if start < best_start or (start == best_start and end < best_end):
best_start = start
best_end = end
# 返回区间的起始和结束位置
return [best_start + 1, best_end + 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])
关键步骤解释
- 初始化:
max_product
用于记录最大乘积,best_start
和best_end
用于记录最大乘积区间的起始和结束位置。 - 遍历数组:使用两个嵌套的循环来遍历所有可能的区间。
- 计算乘积:在内部循环中,计算从
start
到end
的乘积。 - 更新最大乘积:如果当前乘积大于
max_product
,则更新max_product
和区间的起始和结束位置。如果乘积相等,则选择更小的区间。 - 返回结果:返回区间的起始和结束位置,注意数组的起始位置为1,因此需要将
best_start
和best_end
加1。 这道题目使用了暴力枚举算法来解决。具体来说,它通过遍历所有可能的子区间来找到最大乘积区间。
算法复杂度
- 时间复杂度:由于使用了两个嵌套的循环,时间复杂度为
O(n^2)
,其中n
是数组的长度。 - 空间复杂度:空间复杂度为
O(1)
,因为我们只使用了常数个额外的变量。
豆包MarsCode AI 刷题体验
对于题库中的大部分题目,豆包MarsCode AI 都可以一次性生成正确的思路和代码(代码可以一次性通过Marscode测试)。AI提出的思路和代码示例对于刚刚入门算法的初学者来说意义非凡。初学者可以参考这些思路和代码进行自主学习,亦可通过参考这些代码和思路提升学习效率。
目前,豆包MarsCode AI 刷题只支持java和Python,对于编辑区代码的分析功能还有待提升,对于生成的代码,豆包MarsCode AI 不能第一时间给出算法的时间复杂度和空间复杂度(一上来直接点思路或者代码提示),这可能会一定程度上阻碍学习者发掘算法优化的指标和方向。如果豆包MarsCode AI 可以解决以上问题,那么它将成为一款有里程碑意义的编程学习工具。为广大算法学习者带来福音。
在日常学习和科研中,我主要使用Python语言,所以“豆包MarsCode AI 刷题只支持java和Python”这一局限对我影响不大。最希望系统可以尽快支持C/C++,这对于算法党来说是一个福音(编程语言的优势哈哈哈)。
这一次是一道简单的暴力枚举问题,没有太多算法思想,通过暴力枚举所有可能的子区间,我们可以找到最大乘积区间。虽然这种方法的时间复杂度较高,但对于较小的数组(例如 n <= 1000
),这种方法是可行的。