文章目录
  1. 1. 分治法求最大子数组
    1. 1.1. 分治法
    2. 1.2. 最大子数组问题
    3. 1.3. 分治策略思路
    4. 1.4. js实现
    5. 1.5. 验证

分治法求最大子数组的javascript实现。

分治法求最大子数组


分治法

分治策略递归求解一个问题,在每层递归中:

  • 分解(Divide)步骤:将问题划分未一些子问题,子问题的形式与原问题一样,只是规模更小
  • 解决(Conquer)步骤:递归地求解出子问题。如果子问题的规模足够小,则停止递归,直接求解
  • 合并(Combine)步骤:将子问题的解组合成原问题的解

最大子数组问题

求数组的和最大的非空连续子数组,即最大子数组。

分治策略思路

将子数组划分为两个规模尽量相等的子数组,A[low, ..., high]的一个最大子数组A[i, .., j]所处的位置必然是三种情况之一:

  • 完全位于子数组A[low, ..., mid]中,low <= i <= j <= mid
  • 完全位于子数组A[mid + 1, ..., high]中,mid <= i <= j <= high
  • 跨越了中点,low <= i <= mid < j <= high

可递归求解A[low, ..., mid]A[mid + 1, ..., high]

求解跨越中点的最大子数组的思路:

  1. 循环求出A[i, ..., mid]以及A[mid + 1, ..., j]的最大和
  2. 合并返回左侧和右侧最大和

js实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
function findMaxSubarray(iArr, low, high) {
// 求解跨越中点的最大子数组
function findMaxCrossingSubarray(arr, low, mid, high) {
var leftSum = arr[mid];
var rightSum = arr[mid + 1];
var left = mid,
right = mid + 1;
// 遍历左侧,找出左侧最大和
for (var i = mid, sum = 0; i >= low; i--) {
sum += arr[i];
if (sum > leftSum) {
leftSum = sum;
left = i;
}
}
// 遍历右侧,找出右侧最大和
for (var j = mid + 1, sum = 0; j <= high; j++) {
sum += arr[j];
if (sum > rightSum) {
rightSum = sum;
right = j;
}
}
return [leftSum + rightSum, left, right];
}
if (high === low) {
// 若只有一个数,返回该数
return [iArr[low], low, high];
} else {
// 取中间数
var mid = parseInt((high + low) / 2);
// 递归求左侧最大子数组
var result1 = findMaxSubarray(iArr, low, mid);
// 递归求右侧最大子数组
var result2 = findMaxSubarray(iArr, mid + 1, high);
// 求跨越中点的最大子数组
var result3 = findMaxCrossingSubarray(iArr, low, mid, high);
// 比较三个子数组,然后返回最大
if (result1[0] > result2[0] && result1[0] > result3[0]) {
return result1;
} else if (result1[0] > result2[0]) {
return result3;
} else {
return result3[0] > result2[0] ? result3 : result2;
}
}
}

验证

1
2
3
var inputArr = [13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7];
findMaxSubarray(inputArr, 0, inputArr.length - 1);
// 输出[43, 7, 10],即最大和43,子数组为inputArr[7, 10]

查看Github有更多内容噢:https://github.com/godbasin
更欢迎来被删的前端游乐场边撸猫边学前端噢

码生艰难,写文不易,给我家猪囤点猫粮了喵~

作者:被删

出处:https://godbasin.github.io

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

文章目录
  1. 1. 分治法求最大子数组
    1. 1.1. 分治法
    2. 1.2. 最大子数组问题
    3. 1.3. 分治策略思路
    4. 1.4. js实现
    5. 1.5. 验证