package class026; import java.util.ArrayList; import java.util.List; public class Code01_SubArrayMaxSum { public static int test(int[] arr) { if (arr == null || arr.length == 0) { return 0; } int N = arr.length; int max = Integer.MIN_VALUE; for (int L = 0; L < N; L++) { for (int R = L; R < N; R++) { // arr[L...R] int sum = 0; for (int i = L; i <= R; i++) { sum += arr[i]; } max = Math.max(max, sum); } } return max; } public static int dp1(int[] arr) { if (arr == null || arr.length == 0) { return 0; } int[] dp = new int[arr.length]; // dp[i] 子数组必须以i位置结尾的情况下,能得到的最大累加和 dp[0] = arr[0]; for (int i = 1; i < arr.length; i++) { int p1 = arr[i]; int p2 = dp[i - 1] + arr[i]; dp[i] = Math.max(p1, p2); } int max = Integer.MIN_VALUE; for (int i = 0; i < dp.length; i++) { max = Math.max(max, dp[i]); } return max; } public static int dp2(int[] arr) { if (arr == null || arr.length == 0) { return 0; } int preDp = arr[0]; int max = preDp; for (int i = 1; i < arr.length; i++) { int p1 = arr[i]; int p2 = preDp + arr[i]; int dp = Math.max(p1, p2); max = Math.max(max, dp); preDp = dp; } return max; } public static int maxSum(int[] arr) { if (arr == null || arr.length == 0) { return 0; } int cur = 0; int max = Integer.MIN_VALUE; for (int i = 0; i < arr.length; i++) { cur += arr[i]; max = Math.max(max, cur); cur = cur < 0 ? 0 : cur; } return max; } public static int maxSum1(int[] arr) { if (arr == null || arr.length == 0) { return 0; } // 0结尾时候的答案 int pre = arr[0]; int max = arr[0]; for (int i = 1; i < arr.length; i++) { // i结尾时候的答案 pre = arr[i] + (pre > 0 ? pre : 0); max = Math.max(max, pre); } return max; } public static List> maxSum2(int[] arr) { List> ans = new ArrayList<>(); if (arr == null || arr.length == 0) { return ans; } int L = 0; int maxLen = 0; int maxSum = Integer.MIN_VALUE; int cur = 0; for (int i = 0; i < arr.length; i++) { // L...i sum cur += arr[i]; if (cur == maxSum && (i - L + 1) == maxLen) { List curAns = new ArrayList<>(); curAns.add(L); curAns.add(i); ans.add(curAns); } if (cur > maxSum || (cur == maxSum && (i - L + 1) > maxLen)) { ans.clear(); List curAns = new ArrayList<>(); curAns.add(L); curAns.add(i); ans.add(curAns); maxLen = i - L + 1; } maxSum = Math.max(maxSum, cur); if (cur < 0) { cur = 0; L = i + 1; } } return ans; } public static int[] generateArray(int N, int V) { int n = (int) (Math.random() * N) + 1; int[] arr = new int[n]; for (int i = 0; i < n; i++) { arr[i] = (int) (Math.random() * V) - (int) (Math.random() * V); } return arr; } public static void main(String[] args) { int N = 100; int V = 100; int testTime = 10000; System.out.println("test begin"); for (int i = 0; i < testTime; i++) { int[] arr = generateArray(N, V); int ans1 = test(arr); int ans2 = dp1(arr); int ans3 = dp2(arr); if (ans1 != ans2 || ans1 != ans3) { System.out.println("Oops!"); } } System.out.println("test finish"); int[] test = { 2, 2, 1, -9, 2, 3, -9, 6, -9, 2, 2, 2, -9, 2, 2, 2, -9, 1, 4, 1 }; List> ans = maxSum2(test); for (List cur : ans) { System.out.println("start : " + cur.get(0) + ", end : " + cur.get(1)); } } }