Skip to content

Commit 94b629d

Browse files
committed
improving the style of 014
1 parent 987518e commit 94b629d

File tree

4 files changed

+65
-47
lines changed

4 files changed

+65
-47
lines changed

014. Maximum Subarray/README.md

+35-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ benefited = max(A[i], benefited + A[i]);
1515
maxv = max(benefited, maxv);
1616
```
1717

18-
聪明的你一定发现了,第一句条恰是**当权者的决策**,第二条恰是**历史学家的总结**。 横批:人类是贪婪的。
18+
聪明的你一定发现了,第一句条恰是**当权者的决策**,第二条恰是**历史学家的总结**。 横批:人类是贪婪的。
1919

2020
所以不要怪任何一方,从他们的立场看,都是最优解。局部最优能否导致整体最优呢? 千年谜题。
2121

@@ -30,3 +30,37 @@ maxv = max(benefited, maxv);
3030
>If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle
3131
3232
咳咳咳, @Mooophy ,该出来了。。。
33+
34+
-----
35+
36+
@Mooophy 应约而出,给出了[代码](#8),我根据其代码,尝试分析一下分治法的策略:
37+
38+
分治法的灵魂在于一个 **"分"** 字。对于这道题而言,求`A`的最大和子序列,可以给`A`来一刀:
39+
40+
−2,1,−3,4,−1,2,1,−5,4
41+
left | right
42+
crossing
43+
44+
由于子序列连续,它必然属于上述划分中的某一种情况:
45+
46+
- 完全属于 left 部分
47+
- 完全属于 right 部分
48+
- 属于 crossing 部分(即跨越中点)
49+
50+
于是其核心代码如下:
51+
52+
```cpp
53+
int maxSubArray(int A[], int l, int h) {
54+
if (l == h) return A[l]; // 仅有一个数
55+
int m = (l + h) / 2; // 中点位置(划分点)
56+
return std::max({maxSubArray(A, l, m), maxSubArray(A, m+1, h), maxCrossing(A, l, m, h)});
57+
}
58+
```
59+
60+
是否非常的简洁呢?
61+
62+
下面问题集中在 `maxCrossing` 的策略,这个过程可以线性求出。即将其属于 `left` 范畴的 `sum` 与属于 `right` 范畴的 `sum` 加起来即可。
63+
64+
实现代码请见:[divide_conquer.h](divide_conquer.h)
65+
66+
这部分的详细思路可参考 CLRS 的第四章分治法的第一小节。
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#include <algorithm>
2+
#include <climits>
3+
4+
class Solution {
5+
int maxCrossing(int A[], int l, int m, int h) {
6+
int left_max = INT_MIN, right_max = INT_MIN;
7+
for (int i=m, sum=0; i >= l; --i) {
8+
sum += A[i];
9+
if (left_max < sum) left_max = sum;
10+
}
11+
for (int i=m+1, sum=0; i <= h; ++i) {
12+
sum += A[i];
13+
if (right_max < sum) right_max = sum;
14+
}
15+
return left_max + right_max;
16+
}
17+
18+
int maxSubArray(int A[], int l, int h) {
19+
if (l == h) return A[l];
20+
int m = (l + h) / 2;
21+
return std::max({maxSubArray(A, l, m), maxSubArray(A, m+1, h), maxCrossing(A, l, m, h)});
22+
}
23+
public:
24+
int maxSubArray(int A[], int n) {
25+
return maxSubArray(A, 0, n-1);
26+
}
27+
};

014. Maximum Subarray/main.cc

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
#include <iostream>
22
#include "solution.h"
3+
//#include "divide_conquer.h"
34

45
int main()
56
{
6-
int A[] = {-2,1,-3,4,-1,2,1,-5,4};
7+
int A[] = {-2,1,-3,4,-1,2,1,-5,4};
78
Solution s;
89
std::cout << s.maxSubArray(A, 9) << std::endl;
910

10-
SolutionByDivideAndConquer dac;
11-
std::cout << s.maxSubArray(A, 9) << std::endl;
12-
1311
return 0;
14-
}
12+
}

014. Maximum Subarray/solution.h

-41
Original file line numberDiff line numberDiff line change
@@ -12,44 +12,3 @@ class Solution {
1212
return maxv;
1313
}
1414
};
15-
16-
class SolutionByDivideAndConquer{
17-
//O(n)
18-
int find_max_crossing_subarray(int arr[], unsigned low, unsigned mid, unsigned hgh)
19-
{
20-
auto accumulation = 0;
21-
22-
auto lft_sum = accumulation = arr[mid];
23-
if (mid > low)
24-
for (auto i = mid - 1; i != low - 1; --i)
25-
if ((accumulation += arr[i]) > lft_sum)
26-
lft_sum = accumulation;
27-
28-
auto rht_sum = accumulation = arr[mid + 1];
29-
if (hgh > mid)
30-
for (auto i = mid + 2; i != hgh + 1; ++i)
31-
if ((accumulation += arr[i]) > rht_sum)
32-
rht_sum = accumulation;
33-
34-
return lft_sum + rht_sum;
35-
}
36-
37-
//O(n lg n)
38-
int divide_and_conquer(int arr[], unsigned low, unsigned hgh)
39-
{
40-
if (low == hgh) return arr[low];
41-
42-
auto mid = (low + hgh) / 2;
43-
auto lft = divide_and_conquer(arr, low, mid);
44-
auto rht = divide_and_conquer(arr, mid + 1, hgh);
45-
auto crs = find_max_crossing_subarray(arr, low, mid, hgh);
46-
47-
return std::max({ lft, rht, crs });
48-
}
49-
50-
public:
51-
int maxSubArray(int A[], int n)
52-
{
53-
return divide_and_conquer(A, 0, n - 1);
54-
}
55-
};

0 commit comments

Comments
 (0)