|
|
@@ -0,0 +1,83 @@
|
|
|
+package leetcode.p53;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @ProjectName: LeetCode
|
|
|
+ * @FileName: Solution
|
|
|
+ * @Author: 杨逸
|
|
|
+ * @Data:2026/3/23 22:33
|
|
|
+ * @Description: https://leetcode.cn/problems/maximum-subarray/description/
|
|
|
+ * 53. 最大子数组和
|
|
|
+ */
|
|
|
+public class Solution {
|
|
|
+ public int maxSubArray(int[] nums) {
|
|
|
+ /**
|
|
|
+ * 动态规划解法
|
|
|
+ * 1.当i=0为数组末尾时,num[i]就是最大子数组和
|
|
|
+ * 2.当i>0为数组末尾时,max(dp[i-1],0) + nums[i]就是最大子数组和
|
|
|
+ * max(dp[i-1],0)表示当子数组长度为i-1时,如何子数组和大于0则i续上子数组,否则重新开始子数组
|
|
|
+ * 3.维护所有情况下最大的子数组和就是答案
|
|
|
+ */
|
|
|
+ int res = nums[0];
|
|
|
+ //空间优化
|
|
|
+ int pre = nums[0];
|
|
|
+ for (int i = 1; i < nums.length; i++) {
|
|
|
+ int current = Math.max(pre,0) + nums[i];
|
|
|
+ res = Math.max(res,current);
|
|
|
+ pre = current;
|
|
|
+ }
|
|
|
+ return res;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 动态规划解法
|
|
|
+ * @param nums
|
|
|
+ * @return int
|
|
|
+ * @description:
|
|
|
+ * @author: 杨逸
|
|
|
+ * @data:2026/03/23 23:08:52
|
|
|
+ * @since 1.0.0
|
|
|
+ */
|
|
|
+ private int dp(int[] nums){
|
|
|
+ /**
|
|
|
+ * 动态规划解法
|
|
|
+ * 1.当i=0为数组末尾时,num[i]就是最大子数组和
|
|
|
+ * 2.当i>0为数组末尾时,max(dp[i-1],0) + nums[i]就是最大子数组和
|
|
|
+ * max(dp[i-1],0)表示当子数组长度为i-1时,如何子数组和大于0则i续上子数组,否则重新开始子数组
|
|
|
+ * 3.维护所有情况下最大的子数组和就是答案
|
|
|
+ */
|
|
|
+ int res = nums[0];
|
|
|
+ int[] dp = new int[nums.length];
|
|
|
+ dp[0] = nums[0];
|
|
|
+ for (int i = 1; i < nums.length; i++) {
|
|
|
+ dp[i] = Math.max(dp[i-1],0) + nums[i];
|
|
|
+ res = Math.max(res,dp[i]);
|
|
|
+ }
|
|
|
+ return res;
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 前缀和解法
|
|
|
+ * @param nums
|
|
|
+ * @return int
|
|
|
+ * @description:
|
|
|
+ * @author: 杨逸
|
|
|
+ * @data:2026/03/23 22:43:46
|
|
|
+ * @since 1.0.0
|
|
|
+ */
|
|
|
+ private int prefix(int[] nums){
|
|
|
+ /**
|
|
|
+ * 前缀和
|
|
|
+ * 维护前缀和最小值,当前前缀和 减去最小前缀和 即为当前最大子数组和
|
|
|
+ */
|
|
|
+ int min = 0;
|
|
|
+ int[] prefix = new int[nums.length];
|
|
|
+ prefix[0] = nums[0];
|
|
|
+ int res = prefix[0] - min;
|
|
|
+ min = Math.min(min,prefix[0]);
|
|
|
+ for (int i = 1; i < nums.length; i++) {
|
|
|
+ prefix[i] = prefix[i-1] + nums[i];
|
|
|
+ res = Math.max(res,prefix[i] - min);
|
|
|
+ min = Math.min(min,prefix[i]);
|
|
|
+ }
|
|
|
+ return res;
|
|
|
+ }
|
|
|
+}
|