爨爨爨好

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

▶ 求一个整数数列的和最大子串

● 代码,12 ms,动态规划,时间复杂度 O(n),最快的解法算法与之相同。记 f( i ) 为 “数组 num 中以第 i 位作为结尾的子串的最大和”,那么有 f(i) = nums[i] + (f(i - 1) > 0 ? f(i - 1) : 0); 

 1 class Solution
 2 {
 3 public:
 4     int maxSubArray(vector<int>& nums)
 5     {
 6         const int n = nums.size();
 7         if (n == 0)
 8             return 0;
 9         int ans, i, sum;
10         for (i = sum = 0, ans = nums[0]; i < n; i++)
11         {
12             sum += nums[i];     // 更新累积和
13             ans = max(sum, ans);// 更新 ans
14             sum = max(sum, 0);  // 累积和一旦变负,前面的都不要了(默认只有负数的情况下一个都不选和最大)
15         }
16         return ans;
17     }
18 };

● 代码,12 ms,分治思想,最大和子串可以分解为四种相互联系的情况

 1 class Solution
 2 {
 3 public:
 4     val dac(vector<int>& nums, int start,int end)
 5     {
 6         if (start == end)// 数组中只有一个元素,四种和都相等
 7             return val(nums[start], nums[start], nums[start], nums[start]);
 8         val v1 = dac(nums, start, (start + end) / 2), v2 = dac(nums, (start + end) / 2 + 1, end);// 计算前半段和后半段的各种和
 9         int l, m, r, s;
10         l = max(v1.l, v1.s + v2.l);             // 从 num[start] 开始的最大和子串
11         m = max(v1.r + v2.l, max(v1.m, v2.m));  // 夹在中间的最大和子串,可以包含或不含 nums[start] 与 nums[end] 
12         r = max(v2.r, v1.r + v2.s);             // 以 nums[end] 结尾的最大和子串
13         s = v1.s + v2.s;                        // 整个数组的和
14         return val(l, m, r, s);
15     }
16     int maxSubArray(vector<int>& nums)
17     {
18         val v = dac(nums, 0, nums.size() - 1);
19         return v.m;
20     }
21 };

 

posted on 2018-01-30 12:18  爨爨爨好  阅读(137)  评论(0编辑  收藏  举报