最大连续子数组
2013-05-07 18:08
239 查看
题目:
输入一个整形数组,数组里有正数也有负数。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
求所有子数组的和的最大值。要求时间复杂度为O(n)。
例如输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2,
因此输出为该子数组的和18。
解法一:最基本的轮询
思路:
找出所有的连续子数组,求和,比较。算法复杂度o(n^3)
代码:
解法二:去除多余的求和
思路:
sum[i,j] = sum[i, j-1] + sum[j]。算法复杂度o(n^2)
代码:
解法三:专家给出的最优解
思路:
这种方法的证明是个难点。
代码:
输入一个整形数组,数组里有正数也有负数。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
求所有子数组的和的最大值。要求时间复杂度为O(n)。
例如输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2,
因此输出为该子数组的和18。
解法一:最基本的轮询
思路:
找出所有的连续子数组,求和,比较。算法复杂度o(n^3)
代码:
/* 最基本的轮询 */ int maxSubarray(int *a) { int len = a.length; int sum; int max = (1 << 31); //两个外层循环确定子数组头和尾,然后求和 for(int head = 0; head < len; ++head) { for(int tail = head; tail < len; ++tail) { sum = 0; for(int i = head; i <= tail; ++i) sum += a[i]; if(max < sum) max = sum; } } return max; }
解法二:去除多余的求和
思路:
sum[i,j] = sum[i, j-1] + sum[j]。算法复杂度o(n^2)
代码:
/* 去除中间多余的求和 简单的轮询有个明显的缺点:以第一个节点为头的子数组有a.length个;同时计算a[0] + a[1]的次数是a.length-1次; 因为 a[0] a[0] + a[1] a[0] + a[1] + a[2] …… 其实可以这样 a[0] = x a[0] + a[1] = x + a[1] = y a[0] + a[1] + a[2] = y + a[2] …… */ int maxSubarray(int *a) { int len = a.length; int sum; int max = (1 << 31); //两个外层循环确定子数组头和尾,然后求和 for(int head = 0; head < len; ++head) { sum = 0; for(int tail = head; tail < len; ++tail) { sum += a[tail]; if(max < sum) max = sum; } } return max; }
解法三:专家给出的最优解
思路:
这种方法的证明是个难点。
代码:
/* 统计学家提出的最优解 */ int maxSubarray(int *a) { int len = a.length; int sum = 0; int max = (1 << 31); for(int i = 0; i < len; ++i) { sum += a[i]; if(max < sum) max = sum; if(sum < 0) sum = 0; } return max; }
相关文章推荐
- 连续子数组的最大和
- 求连续子数组最大乘积
- 最大连续子数组和
- 最大连续子数组(分治法、动态规划)
- 连续子数组的最大和
- (java)整数数组中求最大连续子序列之和,并且记录开始和结束位置
- 连续子数组的最大和
- 剑指offer(15)-连续子数组的最大和
- 算法学习-连续子数组求和最大值
- 求数组的连续子序列最大和
- 求连续子数组和的最大值的变种问题
- 剑指offer 机器人的运动范围 矩阵中的路径 滑动窗口最大值 次数超过一半的数 连续子数组的最大和
- 求连续子数组最大和
- 连续子数组的最大和
- 最大连续子数组和
- 连续子数组最大和问题(能够处理全是负数,返回子数组的起止索引的O(N)算法)
- 求连续子数组的最大和
- 连续子数组的最大和(java版)
- 《编程之法》:最大连续子数组和
- js实现求连续子数组的最大和并输出下标