题一:子数组的最大累加和
给定一个数组arr,返回子数组的最大累加和
例如:arr=[1,-2,3,5,-2,6,-1], 所有的子数组中[3,5,-2,6]可以累加出最大的和12,所以返回12.
【要求】arr的长度为N,时间复杂度为O(N),额外空间复杂度为O(1)
【思路】用变量记录cur记录每一步的累加和,遍历到正数cur增加,遍历到负数cur减少。
当cur<0时,说明累加到当前数出现了小于0的结果,那么累加的这一部分肯定不能
作为产生最大累加和的子数组的左边部分,此时令cur = 0.表示从下一个数开始累加。
当cur>=0,每一次累加都可能是最大的累加和。用max跟踪记录cur出现的最大值。
cur累加成为负数就清零重新累加,max记录cur的最大值即可。
c++代码实现
#include <iostream> #include <climits> //C++中的头文件 using namespace std; int maxSumSubArr(int *arr, int n){ if (arr == NULL || n < 1) return 0; int res = INT_MIN; //结果 int cur = 0; //当前和 for (int i = 0; i < n; i++){ cur += arr[i]; //直接依次加上 res = max(res, cur); cur = cur < 0 ? 0 : cur; } return res; } int main(){ int arr[] = {-2, 1, 3, -2, 1, -2, 1}; cout << maxSumSubArr(arr, 7); return 0; }
java代码实现
public int maxSum(int []arr){ if (arr == NULL || arr.length==0) return 0; int max = Integer.MIN_VALUE; //结果 int cur = 0; //当前和 for (int i = 0; i < arr.length; i++){ cur += arr[i]; //直接依次加上 max = Math.max(max, cur); cur = cur < 0 ? 0 : cur; } return max; }
题二:子矩阵的最大累加和给定一个矩阵matrix, 其中有正、有负、有0,返回子矩阵的最大累加和。
例如,矩阵matrix为
-90 48 78
64 -40 64
-81 -7 66
其中,最大累加和的子矩阵为:
48 78
-40 64
-7 66
返回累加和209
int maxSumSubMatrix(vector<vector<int>> matrix){ if (matrix.empty() || matrix.size() ==0 || matrix[0].size() == 0) return 0; int res = INT_MIN; int cur = 0; int *s = NULL; //累加数组 for (int i = 0; i < matrix.size(); i++){ s = new int[matrix[0].size()]; //每一列的最大累加和 for (int j = i; j < matrix.size(); j++){ cur = 0; for (int k = 0; k < matrix[0].size(); k++){ s[k] += matrix[j][k]; cur += s[k]; res = max(res, cur); cur = cur < 0 ? 0 : cur; } } } return res; }
参考博客:http://www.cnblogs.com/cnblogsnearby/p/5318525.html
参考书目:《程序员代码面试指南》---左程云著