leetcode0053最大子序和

題目描述

在這裏插入圖片描述

方法一:分治法

這個是使用分治法解決問題的典型的例子,並且可以用與合併排序相似的算法求解。下面是用分治法解決問題的模板:

  • 定義基本情況。
  • 將問題分解爲子問題並遞歸地解決它們。
  • 合併子問題的解以獲得原始問題的解。
class Solution {
  public int crossSum(int[] nums, int left, int right, int p) {
    if (left == right) return nums[left];

    int leftSubsum = Integer.MIN_VALUE;
    int currSum = 0;
    for(int i = p; i > left - 1; --i) {
      currSum += nums[i];
      leftSubsum = Math.max(leftSubsum, currSum);
    }

    int rightSubsum = Integer.MIN_VALUE;
    currSum = 0;
    for(int i = p + 1; i < right + 1; ++i) {
      currSum += nums[i];
      rightSubsum = Math.max(rightSubsum, currSum);
    }

    return leftSubsum + rightSubsum;
  }

  public int helper(int[] nums, int left, int right) {
    if (left == right) return nums[left];

    int p = (left + right) / 2;

    int leftSum = helper(nums, left, p);
    int rightSum = helper(nums, p + 1, right);
    int crossSum = crossSum(nums, left, right, p);

    return Math.max(Math.max(leftSum, rightSum), crossSum);
  }

  public int maxSubArray(int[] nums) {
    return helper(nums, 0, nums.length - 1);
  }
}

複雜度分析

時間複雜度:O(NlogN)。
空間複雜度:O(logN),遞歸時棧使用的空間。

方法二:貪心

使用單個數組作爲輸入來查找最大(或最小)元素(或總和)的問題,貪心算法是可以在線性時間解決的方法之一。
每一步都選擇最佳方案,到最後就是全局最優的方案。
算法:
該算法通用且簡單:遍歷數組並在每個步驟中更新:

  • 當前元素
  • 當前元素位置的最大和
  • 迄今爲止的最大和
class Solution {
  public int maxSubArray(int[] nums) {
    int n = nums.length;
    int currSum = nums[0], maxSum = nums[0];

    for(int i = 1; i < n; ++i) {
      currSum = Math.max(nums[i], currSum + nums[i]);
      maxSum = Math.max(maxSum, currSum);
    }
    return maxSum;
  }
}

複雜度分析

時間複雜度:O(N)。只遍歷一次數組。
空間複雜度:O(1),只使用了常數空間。

方法三:動態規劃(Kadane 算法)

算法:

在整個數組或在固定大小的滑動窗口中找到總和或最大值或最小值的問題可以通過動態規劃(DP)在線性時間內解決。
有兩種標準 DP 方法適用於數組:
常數空間,沿數組移動並在原數組修改。
線性空間,首先沿 left->right 方向移動,然後再沿 right->left 方向移動。 合併結果。
我們在這裏使用第一種方法,因爲可以修改數組跟蹤當前位置的最大和。
下一步是在知道當前位置的最大和後更新全局最大和。

class Solution {
  public int maxSubArray(int[] nums) {
    int n = nums.length, maxSum = nums[0];
    for(int i = 1; i < n; ++i) {
      if (nums[i - 1] > 0) nums[i] += nums[i - 1];
      maxSum = Math.max(nums[i], maxSum);
    }
    return maxSum;
  }
}
發佈了274 篇原創文章 · 獲贊 412 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章