最大子数组问题
来源:互联网 发布:中建上海设计院 知乎 编辑:程序博客网 时间:2024/05/22 03:13
最大子数组问题
问题描述
Find the contiguous subarray within an array (containing at least one number) which has the largest sum.
For example, given the array [−2,1,−3,4,−1,2,1,−5,4],
the contiguous subarray [4,−1,2,1] has the largest sum = 6.
暴力求解法:
# -*- coding:utf-8 -*-def max_subarray(source): sum_max = -float("inf") array_max = [] for i in range(len(source)): for j in range(i+1, len(source)): sum_now = sum(list[i:j+1]) if sum_now > sum_max: sum_max = sum_now array_max = list[i:j+1] return array_maxprint max_subarray([13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7])
分治法:
其实就是分解成最小的子问题,求解跨越数组中点的最大子数组问题
伪代码,摘抄自算法导论P42
FIND-MAX-CROSSING-SUBARRAY(A, low, mid, high)left_sum = - Infsum = 0for i = mid downto lowsum = sum + a[i]if sum > left_sumleft_sum = summax_left = iright_sum = - Infsum = 0for j = mid + 1 to highsum = sum + a[i]if sum > right_sumright_sum = summax_right = jreturn (max_left, max_right, left_sum + right_sum)FIND-MAX-SUBARRAY(A,low,high)if high == low:return (low, high, A[low])elsemid = [(low + high) / 2]//[]是取整(left_low,left_high,left_sum) = FIND-MAX-SUBARRAY(A,low,mid)(right_low,right_high,right_sum) = FIND-MAX-SUBARRAY(A,mid+1,high)(cross_low,cross_high,cross_sum) = FIND-MAX-CROSSING-SUBARRAY(A,low,mid,high)if left_sum >= right_sum and left_sum >= cross_highreturn (left_low, left_high, left_sum)else if right_sum >= left_sum and right_sum >= cross_sumreturn (right_low, right_high, right_sum)elsereturn (cross_low, cross_high, cross_sum)
def max_crossing_subarray(source, low, mid, high): left_sum = float("-Inf") right_sum = float("-Inf") # 累加值初始化为正无穷 sum_now = 0 for i in range(mid, low-1, -1): sum_now = sum(source[mid: i-1: -1]) if sum_now > left_sum: left_sum = sum_now max_left = i sum_now = 0 for j in range(mid+1, high+1): sum_now = sum(source[mid+1:j+1]) if sum_now > right_sum: right_sum = sum_now max_right = j # 找到从mid起始分别到左边和右边的最大子数组 return max_left, max_right, left_sum + right_sum# 将左边的最大子数组与右边的最大子数组合并def max_array(source, low, high): if high == low: return low, high, source[low] else: mid = (low+high)/2 left_low, left_high, left_sum = max_array(source, low, mid) # 左边的最大子数组 right_low, right_high, right_sum = max_array(source, mid+1, high) # 右边的最大子数组 cross_low, cross_high, cross_sum = max_crossing_subarray(source, low, mid, high) # 跨越中点的最大子数组 if left_sum >= right_sum and left_sum >= cross_sum: return left_low, left_high, left_sum elif right_sum >= left_sum and right_sum >= cross_sum: return right_low, right_high, right_sum else: return cross_low, cross_high, cross_sum # 三种情况互相比较,返回最大的情况a = [14, -2, -17, 2, 8, 9, -20, 11]print max_array(a, 0, 7)
阅读全文
0 0
- 最大子数组问题
- 最大子数组问题
- 最大子数组问题
- 最大子数组问题
- 最大子数组问题
- 最大子数组问题
- 最大子数组问题
- 最大子数组问题
- 最大子数组问题
- 最大子数组问题
- 最大子数组问题
- 最大子数组问题
- 最大子数组问题
- 最大子数组问题
- 最大子数组问题
- 最大子数组问题
- 最大子数组问题
- 最大子数组问题
- 选择排序算法(十)
- Java定时任务之Timer(慕课网笔记)
- 【JavaScript】isNaN()函数
- 搭建 react+webpack开发环境
- android fragment 菜单项/工具栏不显示
- 最大子数组问题
- PDF电子书生成目录的快捷方法!!!
- git撤销已经push到远程的commit
- 网易2017内推 [编程题]堆棋子@Java
- 安装beego (windows 版)
- 多边形游戏(博弈)
- HDUOJ 1863 畅通工程(kruskal)
- 银行转账业务-使用事务
- C语言中的atan 与atan2