连续子向量的最大和问题(Python实现)
2012-06-06 00:00
381 查看
问题:
输入:一个向量x,包含n个数。
输出:向量的连续子向量的最大和,以及下标。
首先给出运行结果:
[1, 2, 3, 4]
low= 0 ;high= 4 ;max_sum= 10
[-11, -2, -3, -4]
NULL vector: max_sum = 0
[-1, -2, -3, 4]
low= 3 ;high= 4 ;max_sum= 4
[1, -2, -3, -4]
low= 0 ;high= 1 ;max_sum= 1
[-1, 2, 3, -4]
low= 1 ;high= 3 ;max_sum= 5
[31, -41, 59, 26, -53, 58, 97, -93, -23, 84]
low= 2 ;high= 7 ;max_sum= 187
算法分析:
用有限状态机来解这道题,时间复杂度是O(n). 注:显而易见,如果使用暴力算法的话时间复杂度为O(n^3)。
状态:start, skip, state1, state2, state3, exit
判断条件:元素正负,下表是否在范围内。
根据判断条件在状态件切换,并且记录下表和最大和。
Python实现的源码
输入:一个向量x,包含n个数。
输出:向量的连续子向量的最大和,以及下标。
首先给出运行结果:
[1, 2, 3, 4]
low= 0 ;high= 4 ;max_sum= 10
[-11, -2, -3, -4]
NULL vector: max_sum = 0
[-1, -2, -3, 4]
low= 3 ;high= 4 ;max_sum= 4
[1, -2, -3, -4]
low= 0 ;high= 1 ;max_sum= 1
[-1, 2, 3, -4]
low= 1 ;high= 3 ;max_sum= 5
[31, -41, 59, 26, -53, 58, 97, -93, -23, 84]
low= 2 ;high= 7 ;max_sum= 187
算法分析:
用有限状态机来解这道题,时间复杂度是O(n). 注:显而易见,如果使用暴力算法的话时间复杂度为O(n^3)。
状态:start, skip, state1, state2, state3, exit
判断条件:元素正负,下表是否在范围内。
根据判断条件在状态件切换,并且记录下表和最大和。
Python实现的源码
#!/usr/bin/python # identify the subvector in a given vector that has the maximum sum # Global Vars max_sum = 0 high = 0 low = 0 minus_sum = 0 cur_sum = 0 cur_low = 0 vector = [1, 2, 3, 4] #vector = [-1, -1, -1, -1] #vector = [-1, -1, -1, 1] def check_range(pos): global vector if pos >= 0 and pos < len(vector): return True else: return False def do_start(pos): global vector global low if not check_range(pos): do_exit() return if vector[pos] > 0: low = pos do_state1(pos) return else: do_skip(pos) return def do_exit(): global low global high global cur_sum global minu_sum global cur_low global max_sum if low >= high: print 'NULL vector: max_sum = 0' else: print 'low=', low, ';high=', high, ';max_sum=', max_sum cur_sum = 0 max_sum = 0 cur_low = 0 minus_sum = 0 low = 0 high = 0 return def do_skip(pos): global vector global low if not check_range(pos): do_exit() return while vector[pos] <= 0: pos += 1 if not check_range(pos): do_exit() return if vector[pos] > 0: low = pos do_state1(pos) return else: print 'we should never get here!' return def do_state1(pos): global max_sum global vector global high max_sum += vector[pos] high = pos+1 # [low, high) pos += 1 if not check_range(pos): do_exit() return if vector[pos] > 0: do_state1(pos) return else: do_state2(pos) return def do_state2(pos): global minus_sum global vector global cur_low minus_sum += vector[pos] pos += 1 if not check_range(pos): do_exit() return if vector[pos] > 0: cur_low = pos do_state3(pos) return else: do_state2(pos) return def do_state3(pos): global vector global cur_sum cur_sum += vector[pos] pos += 1 if not check_range(pos): determine_and_reset(pos) do_exit() return if vector[pos] > 0: do_state3(pos) return else: determine_and_reset(pos) do_state2(pos) return def determine_and_reset(pos): global minus_sum global max_sum global cur_sum global cur_low global vector global low global high sum_total = max_sum + minus_sum + cur_sum if sum_total > max_sum and sum_total > cur_sum: high = pos low = low max_sum = sum_total elif cur_sum >= sum_total and cur_sum > max_sum: high = pos low = cur_low max_sum = cur_sum elif max_sum >= sum_total and max_sum >= cur_sum: high = high low = low else: print 'we should never get here!' cur_sum = 0 cur_low = 0 minus_sum = 0 def test1(): global vector vector = [1, 2, 3, 4] print vector do_start(0) def test2(): global vector vector = [-11, -2, -3, -4] print vector do_start(0) def test3(): global vector vector = [-1, -2, -3, 4] print vector do_start(0) def test4(): global vector vector = [1, -2, -3, -4] print vector do_start(0) def test5(): global vector vector = [-1, 2, 3, -4] print vector do_start(0) def test6(): global vector vector = [31, -41, 59, 26, -53, 58, 97, -93, -23, 84] print vector do_start(0) def main(): test1() test2() test3() test4() test5() test6() return 0 if __name__ == '__main__': main()
相关文章推荐
- 扫描算法求解连续子向量的最大和问题(Python)
- [151225] Python3 实现最大堆、堆排序,解决TopK问题
- 求一个向量的任何连续子向量的最大和的4种算法实现(简单实例)
- 求连续子数组最大和问题的两种解法_PHP实现
- 计算4000000000内的最大f(n)=n值---字符串的问题python实现(五岁以下儿童)
- 连续子向量最大和问题——《编程珠玑》读书笔记
- 计算4000000000以内最大的f(n)=n的值---字符串问题python实现(五)
- PHP实现求连续子数组最大和问题2种解决方法
- Python实现求解最大子数组问题
- HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数
- Python实现最大子树问题
- 一个无聊男人的疯狂《数据结构与算法分析-C++描述》学习笔记 用C++/lua/python/bash的四重实现(3) 最大子序列和问题
- 连续子数组最大和 python版实现
- 连续子序列最大和问题精讲(java实现)
- HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数
- 求最大和连续子向量问题的算法分析
- 类动态规划求解较小规模的最大团问题(Python实现)
- 动态规划--求最大连续子数组的和(Python实现)&求解最大连续乘积字串(Python实现)
- 最大连续子序列问题的java实现
- HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。你会不会被他忽悠住?