第97题 最大乘积区间问题||青训营笔记创作活动

82 阅读4分钟

第97题 小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] 问题分析

1.数组特性:数组元素均来自一个特定的集合,这意味着数组中不会出现除这些元素外的其他数值。 2.乘积计算:由于数组中可能包含0,因此任何包含0的区间乘积都将为0,除非该区间仅包含一个非零元素。 3.区间选择:在存在多个乘积相同的区间时,需按照起始位置x(若x相同则按y)更小的原则来选择。 4.索引转换:题目要求输出基于1的索引,而Python等编程语言通常使用基于0的索引,因此需要进行相应的转换。

关键点

  1. 乘积的特性

    • 由于数组中的元素都是正数或0,乘积的结果要么是正数,要么是0。
    • 如果区间中包含0,那么该区间的乘积为0。
  2. 区间的选择

    • 如果存在多个区间乘积相同的情况,优先选择 x 更小的区间;如果 x 相同,选择 y 更小的区间。

解题思路

  1. 遍历所有可能的区间

    • 我们可以通过两层循环来遍历所有可能的区间 [i, j],其中 i 是区间的起始位置,j 是区间的结束位置。
    • 计算每个区间的乘积,并记录最大乘积及其对应的区间。
  2. 处理0的情况

    • 如果区间中包含0,那么该区间的乘积为0。我们可以选择忽略这些区间,或者在比较时特别处理。
  3. 优化

    • 由于数组中的元素都是正数或0,我们可以利用这个特性来优化计算。例如,当遇到0时,可以直接跳过后续的计算。
    def solution(n, arr):
    
    max_product = float('-inf')
    
    start_idx, end_idx = 1, 1  # 初始化起始与结束位置为1(基于1的索引)
    
    
    
    # 遍历所有可能的区间
    
    for i in range(n):
    
        product = 1
    
        for j in range(i, n):
    
            product *= arr[j]  # 计算当前区间的乘积(注意:这里arr是基于0的索引)
    
            # 由于arr中的元素都是正数(除了0),因此我们可以在遇到0时立即停止内层循环
    
            # 但为了保持与题目要求的一致性(即使乘积为0也要考虑),我们仍然计算整个区间的乘积
    
            # 不过,在后续的比较中,我们可以忽略那些乘积为0且长度不是1的区间
    
            
    
            # 更新最大乘积及其对应区间
    
            if product > max_product:
    
                max_product = product
    
                start_idx = i + 1  # 转换为基于1的索引
    
                end_idx = j + 1    # 转换为基于1的索引
    
            # 如果乘积相等,则根据题目要求不更新或更新为x更小的区间(这里已经隐含在比较中了)
    
    
    
    # 由于题目中可能存在多个0导致某些区间乘积为0,我们需要特别处理这种情况
    
    # 如果最大乘积仍然是负无穷(即没有找到有效的非零乘积区间),则默认选择第一个元素作为区间
    
    # 但根据题目要求和给出的样例,这种情况似乎不会发生,因为至少有一个非零元素存在
    
    # 因此,下面的处理逻辑主要是为了代码的健壮性而添加的
    
    if max_product == float('-inf'):
    
        return [1, 1]  # 默认返回第一个元素作为区间(这是一个保守的选择,实际情况可能需要根据题目具体要求来调整)
    
    
    
    return [start_idx, end_idx]
        
    

    测试样例

    print(find_max_product_interval(5, [1, 2, 4, 0, 8])) # 输出: [1, 3]

    print(find_max_product_interval(7, [1, 2, 4, 8, 0, 256, 0])) # 输出: [6, 6]

    print(find_max_product_interval(8, [1, 2, 4, 8, 0, 256, 512, 0])) # 输出: [6, 7]