我们把数组nums以中间位置(m)分为左(left)右(right)两部分. 那么有,

left = nums[0]...nums[m - 1] 和 right = nums[m + 1]...nums[n-1]

最大子序列和的位置有以下三种情况:

分别求出三种情况下最大子序列和,三者中最大值即为最大子序列和。

举例说明,如下图:

复杂度分析

补充

补充:以"最大子序和"为例,分治三步:

  • 左半部分最大子序和 —— 递归求解。
  • 右半部分最大子序和 —— 递归求解。
  • 横跨中点的最大子序和 —— 从中点向左累加取最大 + 向右累加取最大,二者相加。

三者取最大即答案。复杂度 O(n log n),但实际上 Kadane 算法(动态规划)只需 O(n) 即可解决;分治的价值更多在于"分而治之"的递归思维训练(归并排序、快速排序、最近点对等都使用同一思路)。

function maxSubArray(nums, l = 0, r = nums.length - 1) {
  if (l === r) return nums[l];
  const m = (l + r) >> 1;
  const left = maxSubArray(nums, l, m);
  const right = maxSubArray(nums, m + 1, r);
  let lMax = -Infinity, rMax = -Infinity, s = 0;
  for (let i = m; i >= l; i--) { s += nums[i]; lMax = Math.max(lMax, s); }
  s = 0;
  for (let i = m + 1; i <= r; i++) { s += nums[i]; rMax = Math.max(rMax, s); }
  return Math.max(left, right, lMax + rMax);
}

来源整理自:我的有道云笔记