清晰解题: 寻找最大子数列-Kadane算法
来源:互联网 发布:linux shell脚本编写 编辑:程序博客网 时间:2024/06/05 20:09
本文参考:
Maximum sub array problem
问题: 给定一个数列,例如【−2, 1, −3, 4, −1, 2, 1, −5, 4】, 求一个连续的数列使得数列内的元素和最大, 示例中最大子数列应该是【4, −1, 2, 1】, 求和值为6。
这个问题是可以衍生到一些变种问题, 如寻找数列中最大乘积序列,且要求序列中,相邻元素间隔不超过限定值等, 常出现在笔试面试编程题中。
该问题最早于1977年提出,但是直到1984年才被Jay Kadane 发现了线性时间的最优解法,所以算法虽然长度很短,但其实并不容易理解。
算法描述:
- 遍历该数组, 在遍历过程中, 将遍历到的元素依次累加起来, 当累加结果小于或等于0时, 从下一个元素开始,重新开始累加。
- 累加过程中, 要用一个变量(max_so_far)记录所获得过的最大值
- 一次遍历之后, 变量 max_so_far 中存储的即为最大子片段的和值。
此处为python 代码 , 变量A 传入数组。
def max_subarray(A): max_ending_here = max_so_far = 0 for x in A: max_ending_here = max(0, max_ending_here + x) max_so_far = max(max_so_far, max_ending_here) return max_so_far
首先, 题目中有一个隐含的设定, 最大子片段是可以为空的, 空片段的和值是0。 这一点必须要明确, 不然会无法理解算法的正确性, 所以当给定的数列中,求和为负数的时候,例如【-2,1, -3】, 算法会返回最大求和值0, 因为默认该数组的最大子片段是一个空序列。
理解此算法的关键在于:
- 最大子片段中不可能包含求和值为负的前缀。 例如 【-2, 1,4】 必然不能是最大子数列, 因为去掉值为负的前缀后【-2,1】, 可以得到一个更大的子数列 【4】、
- 所以在遍历过程中,每当累加结果成为一个非正值时, 就应当将下一个元素作为潜在最大子数列的起始元素, 重新开始累加。
- 由于在累加过程中, 出现过的最大值都会被记录, 且每一个可能成为 最大子数列起始元素 的位置, 都会导致新一轮的累加, 这样就保证了答案搜索过程的完备性和正确性。
0 0
- 清晰解题: 寻找最大子数列-Kadane算法
- Kadane算法(值最大的连续子数组)
- Leetcode121.+Leetcode53. Kadane算法解决最大子数组问题
- 一个矩阵的所有子矩阵最大和问题、Kadane算法
- 求最大连续子序列的和,两种解法:动态规划 & Kadane算法
- 从一道easy leetcode问题,谈谈最大子列和的Kadane算法
- Kadane算法
- Kadane算法
- Kadane's algorithm(Kadane算法)
- 在数组中,寻找一个最大递增子数列
- 算法导论寻找最大子数组
- 算法导论之寻找最大子数组
- 算法导论--寻找最大子数组
- 带负数的数列,求解和最大的相邻子序列之二:代码清晰
- 寻找最大子数组
- 最大递增子数列
- 最大子数列和
- 最大连续子数列
- 03 Button 按钮
- Toggle, Tween(完善篇)
- JDBC (数据库连接)
- Activity生命周期探究
- C++友元理解
- 清晰解题: 寻找最大子数列-Kadane算法
- VC----VS2008LINK : fatal error LNK1000: Internal error during IncrBuildImage
- 轮播
- java IO介绍(一)
- Android逆向实例笔记—破解第一个Android程序_crackme02
- C++ 虚函数表解析
- linux之基础shell脚本编程3 函数数组
- JAVA浅层复制深层复制理解-java_01_20160824
- VC----MFC对话框(1)