▶ 求一个整数数列的和最大子串
● 代码,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 };