翻转增益的最大子数组和 | 豆包MarsCode AI 刷题

52 阅读5分钟

问题描述

小C面对一个由整数构成的数组,他考虑通过一次操作提升数组的潜力。这个操作允许他选择数组中的任一子数组并将其翻转,目的是在翻转后的数组中找到具有最大和的子数组。小C对这个可能性很感兴趣,并希望知道翻转后的数组中可能得到的最大子数组和是多少。

例如,数组是 1, 2, 3, -1, 4。小C可以选择翻转子数组 -1, 4 得到 1, 2, 3, 4, -1 或者翻转 1, 2, 3, -1 得到 -1, 3, 2, 1, 4,在这两种情况下,最大的子数组和都是 10。

备注:子数组 是数组中的一个连续部分。

输入

  • N: 数组的长度
  • data_array: 一个长度为 N 的整数数组

输出

请你返回执行翻转操作后(也可以选择不翻转),数组中可能获得的最大子数组和。


测试样例

样例1:

输入:N = 5,data_array = [1, 2, 3, -1, 4]
输出:10

样例2:

输入:N = 4,data_array = [-3, -1, -2, 3]
输出:3

样例3:

输入:N = 3,data_array = [-1, -2, -3]
输出:-1

样例4:

输入:N = 6,data_array = [-5, -9, 6, 7, -6, 2]
输出:15

样例5:

输入:N = 7,data_array = [-8, -1, -2, -3, 4, -5, 6]
输出:10

整体思路

要找到经过一次翻转操作后数组中可能获得的最大子数组和,我们可以考虑遍历数组中的每个子数组,对其进行翻转操作,然后在翻转后的整个数组中找到最大子数组和,最后从所有这些可能的最大子数组和中选取最大值作为最终结果。

具体步骤

  1. 初始化变量

    • 定义一个变量 max_sum 并初始化为一个较小的值(比如数组中的最小值或者负无穷),这个变量将用于存储最终找到的最大子数组和。
  2. 遍历所有可能的子数组进行翻转操作

    • 使用两层嵌套循环来遍历数组中的所有子数组。外层循环控制子数组的起始位置 i,内层循环控制子数组的结束位置 j,这样就可以遍历到数组中的每一个连续子数组。

      • 对于每一个确定的子数组(从索引 i 到索引 j),我们创建一个新的数组 new_array,它是原数组 data_array 的一个副本。

      • 在新数组 new_array 中,对从索引 i 到索引 j 的子数组进行翻转操作。可以通过双指针或者切片等方式来实现翻转,例如在 Python 中可以使用 new_array[i:j+1] = new_array[i:j+1][::-1]

      • 计算翻转后的新数组 new_array 中的最大子数组和。这可以使用经典的求最大子数组和的算法,比如 Kadane 算法。

        • Kadane 算法的基本思想是:定义两个变量,一个是当前最大子数组和 current_max,另一个是全局最大子数组和 global_max。初始化它们都为新数组 new_array 的第一个元素。
        • 然后从数组的第二个元素开始遍历,对于每个元素 new_array[k]k 从 1 到 len(new_array) - 1),计算 current_max = max(new_array[k], current_max + new_array[k]),这表示要么以当前元素开始一个新的子数组,要么将当前元素加入到前面的子数组中。
        • 接着更新 global_max = max(global_max, current_max),确保全局最大子数组和始终记录着到目前为止找到的最大值。
      • 得到翻转后的新数组 new_array 的最大子数组和后,将其与当前的 max_sum 进行比较,如果大于 max_sum,则更新 max_sum 的值为这个新的最大子数组和。

  3. 返回结果

    • 遍历完所有可能的子数组并完成相应的翻转和最大子数组和计算后,max_sum 就存储了经过一次翻转操作后数组中可能获得的最大子数组和,直接返回 max_sum 即可。

实现代码

def solution(N, data_array):
    max_sum = float('-inf')

    for i in range(N):
        for j in range(i, N):
            new_array = data_array.copy()
            new_array[i:j + 1] = new_array[i:j + 1][::-1]

            current_max = new_array[0]
            global_max = new_array[0]

            for k in range(1, len(new_array)):
                current_max = max(new_array[k], current_max + new_array[k])
                global_max = max(global_max, current_max)

            if global_max > max_sum:
                max_sum = global_max

    return max_sum

if __name__ == "__main__":
    #  You can add more test cases here
    array1 = [-85, -11, 92, 6, 49, -76, 28, -16, 3, -29, 26, 37, 86, 3, 25, -43, -36, -27, 45, 87, 91, 58, -15, 91, 5, 99, 40, 68, 54, -95, 66, 49, 74, 9, 24, -84, 12, -23, -92, -47, 5, 91, -79, 94, 61, -54, -71, -36, 31, 97, 64, -14, -16, 48, -79, -70, 54, -94, 48, 37, 47, -58, 6, 62, 19, 8, 32, 65, -81, -27, 14, -18, -34, -64, -97, -21, -76, 51, 0, -79, -22, -78, -95, -90, 4, 82, -79, -85, -64, -79, 63, 49, 21, 97, 47, 16, 61, -46, 54, 44]
    print(solution(5, [1,2,3,-1,4]) == 10 )
    print(solution(100, array1) == 1348)