题目描述:
小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
思路解析:
步骤一:
计算出不做任何反转前的最大子数组和,用Kadaen法:
private static int Kadane(int[] data_array) {
int current_max = data_array[0];
int global_max = data_array[0];
for (int i = 1; i < data_array.length; i++) {
int num = data_array[i];
current_max = Math.max(num, current_max + num);
global_max = Math.max(global_max, current_max);
}
return global_max;
}
步骤二:
实现将某个子数组反转的过程:
private static int[] flipSubarray(int[] array, int start, int end) {
while (start < end) {
int tmp = array[start];
array[start] = array[end];
array[end] = tmp;
end--;
start++;
}
return array;
}
最后:
循环找到最大值:
public static int solution(int N, int[] data_array) {
int maxSumWithFlip = Kadane(data_array);
for (int i = 0; i < N; i++) {
for (int j = i + 1; j < N; j++) {
int[] tmp_array = data_array.clone();
int[] flippedArray = flipSubarray(tmp_array, i, j);
maxSumWithFlip = Math.max(maxSumWithFlip, Kadane(flippedArray));
}
}
return maxSumWithFlip;
}
全部代码:
public static int solution(int N, int[] data_array) {
int maxSumWithFlip = Kadane(data_array);
for (int i = 0; i < N; i++) {
for (int j = i + 1; j < N; j++) {
int[] tmp_array = data_array.clone();
int[] flippedArray = flipSubarray(tmp_array, i, j);
maxSumWithFlip = Math.max(maxSumWithFlip, Kadane(flippedArray));
}
}
return maxSumWithFlip;
}
private static int Kadane(int[] data_array) {
int current_max = data_array[0];
int global_max = data_array[0];
for (int i = 1; i < data_array.length; i++) {
int num = data_array[i];
current_max = Math.max(num, current_max + num);
global_max = Math.max(global_max, current_max);
}
return global_max;
}
private static int[] flipSubarray(int[] array, int start, int end) {
while (start < end) {
int tmp = array[start];
array[start] = array[end];
array[end] = tmp;
end--;
start++;
}
return array;
}