题目描述

原题链接

给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
子数组 是数组中的一个连续部分。

示例 1:
输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。

示例 2:
输入:nums = [1]
输出:1

示例 3:
输入:nums = [5,4,-1,7,8]
输出:23

提示:

  • 1 <= nums.length <= 105
  • -104 <= nums[i] <= 104

进阶:如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的 分治法 求解。

个人解法

Javascript

  1. /*
  2. * @lc app=leetcode.cn id=53 lang=javascript
  3. *
  4. * [53] 最大子数组和
  5. */
  6. // @lc code=start
  7. /**
  8. * @param {number[]} nums
  9. * @return {number}
  10. */
  11. var maxSubArray = function (nums) {
  12. let max = -200000;
  13. let sum = -200000;
  14. const length = nums.length;
  15. for (let i = 0; i < length; i++) {
  16. if (sum + nums[i] > nums[i]) {
  17. sum = sum + nums[i];
  18. } else {
  19. sum = nums[i];
  20. }
  21. if (sum > max) {
  22. max = sum;
  23. }
  24. }
  25. return max;
  26. };
  27. // @lc code=end

简化

  1. var maxSubArray = function(nums) {
  2. let pre = 0, maxAns = nums[0];
  3. nums.forEach((x) => {
  4. pre = Math.max(pre + x, x);
  5. maxAns = Math.max(maxAns, pre);
  6. });
  7. return maxAns;
  8. };

Java

  1. class Solution {
  2. public int maxSubArray(int[] nums) {
  3. int ans = nums[0];
  4. int sum = 0;
  5. for(int num: nums) {
  6. if(sum > 0) {
  7. sum += num;
  8. } else {
  9. sum = num;
  10. }
  11. ans = Math.max(ans, sum);
  12. }
  13. return ans;
  14. }
  15. }

其他解法

Java

分治法

  1. class Solution {
  2. public class Status {
  3. public int lSum, rSum, mSum, iSum;
  4. public Status(int lSum, int rSum, int mSum, int iSum) {
  5. this.lSum = lSum;
  6. this.rSum = rSum;
  7. this.mSum = mSum;
  8. this.iSum = iSum;
  9. }
  10. }
  11. public int maxSubArray(int[] nums) {
  12. return getInfo(nums, 0, nums.length - 1).mSum;
  13. }
  14. public Status getInfo(int[] a, int l, int r) {
  15. if (l == r) {
  16. return new Status(a[l], a[l], a[l], a[l]);
  17. }
  18. int m = (l + r) >> 1;
  19. Status lSub = getInfo(a, l, m);
  20. Status rSub = getInfo(a, m + 1, r);
  21. return pushUp(lSub, rSub);
  22. }
  23. public Status pushUp(Status l, Status r) {
  24. int iSum = l.iSum + r.iSum;
  25. int lSum = Math.max(l.lSum, l.iSum + r.lSum);
  26. int rSum = Math.max(r.rSum, r.iSum + l.rSum);
  27. int mSum = Math.max(Math.max(l.mSum, r.mSum), l.rSum + r.lSum);
  28. return new Status(lSum, rSum, mSum, iSum);
  29. }
  30. }

Javascript

分治法

题解链接

  1. function Status(l, r, m, i) {
  2. this.lSum = l;
  3. this.rSum = r;
  4. this.mSum = m;
  5. this.iSum = i;
  6. }
  7. const pushUp = (l, r) => {
  8. const iSum = l.iSum + r.iSum;
  9. const lSum = Math.max(l.lSum, l.iSum + r.lSum);
  10. const rSum = Math.max(r.rSum, r.iSum + l.rSum);
  11. const mSum = Math.max(Math.max(l.mSum, r.mSum), l.rSum + r.lSum);
  12. return new Status(lSum, rSum, mSum, iSum);
  13. }
  14. const getInfo = (a, l, r) => {
  15. if (l === r) {
  16. return new Status(a[l], a[l], a[l], a[l]);
  17. }
  18. const m = (l + r) >> 1;
  19. const lSub = getInfo(a, l, m);
  20. const rSub = getInfo(a, m + 1, r);
  21. return pushUp(lSub, rSub);
  22. }
  23. var maxSubArray = function(nums) {
  24. return getInfo(nums, 0, nums.length - 1).mSum;
  25. };