问题:
给出一个数组,求出其所有连续子数组中,和最大是多少,注意,这些子数组中,可以选择最多删除一个数。
思路:
这个题目,其实是剑指offer中面试题42:连续子数组的最大和的一个变种。不同之处在于,你找到的子数组,还可以选择删除一个。
而剑指offer里的办法,是通过从头遍历数组,计算以当前元素位置结束时的最大和,并记录各位置中最大的一个和,返回该值。
而我们这里需要处理,去掉一块后的子数组和,会不会比原来的大。
所以我们这里添加一个从尾部遍历数组,计算以当前元素位置开始时的最大和。
那么,在计算所有位置的从这结束的最大和,以及从这开始的最大和。我们只需要再比较抠掉某个元素(假设位置为i)后的最大和,从该位置的前一个(i - 1)结束的最大和 加上 从该位置的后一个(i + 1)开始的最大和,就能知道最大的子数组和。
代码:
1 class Solution { 2 public: 3 int maximumSum(vector<int>& arr) { 4 int n = arr.size(); 5 vector<int> end_here(n); 6 vector<int> start_here(n); 7 int max_sum = arr[0]; 8 end_here[0] = arr[0]; 9 for (int i = 1; i < n; i++) { 10 end_here[i] = max(arr[i], end_here[i - 1] + arr[i]); 11 max_sum = max(max_sum, end_here[i]); 12 } 13 start_here[n - 1] = arr[n - 1]; 14 for (int i = n - 2; i >= 0; i--) { 15 start_here[i] = max(arr[i], start_here[i + 1] + arr[i]); 16 } 17 for (int i = 1; i < n - 1; i++) { 18 max_sum = max(max_sum, end_here[i - 1] + start_here[i + 1]); 19 } 20 return max_sum; 21 } 22 };