53.最大子数组和
链接:53.最大子数组和
难度:Medium
标签:数组、分治、动态规划
简介:给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
题解 1 - python
- 编辑时间:2023-11-20
- 执行用时:168ms
- 内存消耗:30.34MB
- 编程语言:python
- 解法介绍:遍历后记录前面的最小前缀和。
class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        ans = -inf
        prev = 0
        sums = 0
        for num in nums:
            sums += num
            ans = max(ans, sums - prev)
            prev = min(prev, sums)
        return ans
题解 2 - cpp
- 编辑时间:2021-12-21
- 执行用时:164ms
- 内存消耗:66.1MB
- 编程语言:cpp
- 解法介绍:分治,求出左边最大值,右边最大值和中间最大值。
class Solution {
   public:
    int maxSubArray(vector<int>& nums) { return dfs(nums, 0, nums.size() - 1); }
    int dfs(vector<int>& nums, int l, int r) {
        if (l == r) return nums[l];
        int m = (l + r) >> 1, lmax = INT_MIN, rmax = INT_MIN, sum = 0;
        for (int i = m; i >= l; i--) {
            sum += nums[i];
            lmax = max(lmax, sum);
        }
        sum = 0;
        for (int i = m + 1; i <= r; i++) {
            sum += nums[i];
            rmax = max(rmax, sum);
        }
        return max(lmax + rmax, max(dfs(nums, l, m), dfs(nums, m + 1, r)));
    }
};
题解 3 - typescript
- 编辑时间:2021-09-04
- 执行用时:75ms
- 内存消耗:39.5MB
- 编程语言:typescript
- 解法介绍:前缀和,减去前面前缀和的最小值。
function maxSubArray(nums: number[]): number {
  const sums = [0];
  const n = nums.length;
  for (let i = 0; i < n; i++) sums.push(sums[sums.length - 1] + nums[i]);
  let ans = -Infinity;
  let min = 0;
  for (let i = 1; i <= n; i++) {
    ans = Math.max(sums[i] - min, ans);
    min = Math.min(min, sums[i]);
  }
  return ans;
}
题解 4 - cpp
- 编辑时间:2021-12-21
- 执行用时:100ms
- 内存消耗:66MB
- 编程语言:cpp
- 解法介绍:遍历,每次求出前面的最大值。
class Solution {
   public:
    int maxSubArray(vector<int>& nums) {
        int sum = nums[0], ans = sum;
        for (int i = 1; i < nums.size(); i++) {
            sum = max(0, sum) + nums[i];
            ans = max(ans, sum);
        }
        return ans;
    }
};
题解 5 - javascript
- 编辑时间:2020-05-03
- 执行用时:64ms
- 内存消耗:35.4MB
- 编程语言:javascript
- 解法介绍:遍历数组,若前一项大于 0 则当前项+=前一项,最后获取数组中的最大值。
/**
 * @param {number[]} nums
 * @return {number}
 */
var maxSubArray = function (nums) {
  const len = nums.length;
  let max = nums[0];
  if (len === 1) return nums[0];
  for (let i = 1; i < len; i++) {
    if (nums[i - 1] > 0) nums[i] += nums[i - 1];
    if (max < nums[i]) max = nums[i];
  }
  return max;
};
题解 6 - typescript
- 编辑时间:2021-05-14
- 执行用时:92ms
- 内存消耗:40.5MB
- 编程语言:typescript
- 解法介绍:利用前缀和进行快速相减。
function maxSubArray(nums: number[]): number {
  const len = nums.length;
  const prefixSumList = [0];
  for (let i = 1; i <= len; i++) prefixSumList[i] = prefixSumList[i - 1] + nums[i - 1];
  let min = prefixSumList[0];
  let ans = nums[0];
  for (let i = 1; i <= len; i++)
    ans = Math.max(prefixSumList[i] - (min = Math.min(min, prefixSumList[i - 1])), ans);
  return ans;
}
题解 7 - javascript
- 编辑时间:2020-05-10
- 执行用时:92ms
- 内存消耗:34.8MB
- 编程语言:javascript
- 解法介绍:跟题解 3 思路一样,优化空间。
/**
 * @param {number[]} nums
 * @return {number}
 */
var maxSubArray = function (nums) {
  const len = nums.length;
  if (nums == null || len == 0) return 0;
  let max = (dp = nums[0]);
  for (let i = 1; i < len; i++) max = Math.max(max, (dp = Math.max(0, dp) + nums[i]));
  return max;
};
题解 8 - typescript
- 编辑时间:2021-07-22
- 执行用时:72ms
- 内存消耗:39.9MB
- 编程语言:typescript
- 解法介绍:单调递增队列。
function maxSubArray(nums: number[]): number {
  if (nums.length === 1) return nums[0];
  const sums = [0];
  nums.forEach((num, i) => sums.push(sums[i] + num));
  const queue: number[] = [0];
  let ans = -Infinity;
  for (let i = 1; i <= nums.length; i++) {
    const num = sums[i];
    ans = Math.max(ans, num - queue[0]);
    while (queue.length && queue[queue.length - 1] > num) queue.pop();
    queue.push(num);
  }
  return ans;
}
题解 9 - javascript
- 编辑时间:2020-05-07
- 执行用时:80ms
- 内存消耗:35.2MB
- 编程语言:javascript
- 解法介绍:分治法。
/**
 * @param {number[]} nums
 * @return {number}
 */
var maxSubArray = function (nums) {
  if (nums === null || nums.length === 0) return 0;
  return _maxSubArray(nums, 0, nums.length);
  function _maxSubArray(nums, begin, end) {
    if (end - begin < 2) return nums[begin];
    const mid = (begin + end) >> 1;
    let leftMax = -Infinity;
    let leftSum = 0;
    for (let i = mid - 1; i >= begin; i--) {
      leftSum += nums[i];
      leftMax = Math.max(leftMax, leftSum);
    }
    let rightMax = -Infinity;
    let rightSum = 0;
    for (let i = mid; i < end; i++) {
      rightSum += nums[i];
      rightMax = Math.max(rightMax, rightSum);
    }
    const max = leftMax + rightMax;
    return Math.max(max, _maxSubArray(nums, begin, mid), _maxSubArray(nums, mid, end));
  }
};
题解 10 - typescript
- 编辑时间:2021-07-17
- 执行用时:4620ms
- 内存消耗:46.1MB
- 编程语言:typescript
- 解法介绍:前缀和。
function maxSubArray(nums: number[]): number {
  let num = 0;
  const len = nums.length;
  const sums = [0, ...nums.map(v => (num += v))];
  let ans = -Infinity;
  for (let i = 0; i < len; i++) {
    ans = Math.max(ans, nums[i]);
    const sum = sums[i + 1];
    for (let j = 0; j < i; j++) {
      const num = sum - sums[j];
      ans = Math.max(ans, num);
    }
  }
  return ans;
}
题解 11 - typescript
- 编辑时间:2021-07-22
- 执行用时:72ms
- 内存消耗:39.6MB
- 编程语言:typescript
- 解法介绍:取最大值。
function maxSubArray(nums: number[]): number {
  let ans = -Infinity;
  let max = 0;
  for (let i = 0; i < nums.length; i++) {
    if (max > 0) max += nums[i];
    else max = nums[i];
    ans = Math.max(ans, max);
  }
  return ans;
}
题解 12 - typescript
- 编辑时间:2021-07-17
- 执行用时:88ms
- 内存消耗:47.6MB
- 编程语言:typescript
- 解法介绍:前缀和。
function maxSubArray(nums: number[]): number {
  let num = 0;
  const len = nums.length;
  const sums = [0, ...nums.map(v => (num += v))];
  let min = 0;
  let ans = -Infinity;
  for (let i = 0; i < len; i++) {
    const sum = sums[i + 1];
    ans = Math.max(ans, sum - min, nums[i]);
    min = Math.min(min, sum);
  }
  return ans;
}
题解 13 - javascript
- 编辑时间:2020-05-10
- 执行用时:64ms
- 内存消耗:35.9MB
- 编程语言:javascript
- 解法介绍:动态规划,递推,dp[i]=以 nums[i]结尾的子序列和。
/**
 * @param {number[]} nums
 * @return {number}
 */
var maxSubArray = function (nums) {
  const len = nums.length;
  if (nums == null || len == 0) return 0;
  const dp = [nums[0]];
  let max = dp[0];
  for (let i = 1; i < len; i++) max = Math.max(max, (dp[i] = Math.max(0, dp[i - 1]) + nums[i]));
  return max;
};