4.1-1 当A的所有元素均为负数时,FIND-MAXIMUM-SUBARRAY 返回什么?
答:最大的数组元素。
4.1-2 对最大子数组问题,编写暴力求解方法的伪代码, 其运行时间应该为Θ(n²)。
答:
sum(A, low, high)
sum = 0
for i = low to high
sum += A[i]
return sum
FIND-MAX-SUBARRAY(A, n)
max_sum = -∞
max_left = 0
max_right = 0
for i= 1 to n
for j=i to n
temp_sum = sum(A, i, j)
if temp_sum > max_sum
max_sum = temp_sum
max_left = i
max_right = j
return (max_left, max_right, max_sum)
4.1-3 在你的计算机上实现最大子数组问题的暴力算法和递归算法。请指出多大的问题规模n0是性能交叉点——从此之后递归算法将击败暴力算法?然后,修改递归算法的基本情况——当问题规模小于n0时采用暴力算法。修改后,性能交叉点会改变吗?
答:
暴力求解算法
def sum(a, low, high):
sum = 0
for i in range(low, high,1):
sum += a[i]
return sum
def find_max_subarray(a, n):
max_sum = 0
left_sum = 0
right_sum = 0
for i in range(0,n-1, 1):
for j in range(i, n-1, 1):
temp_sum = sum(a, i, j)
if temp_sum > max_sum:
max_sum = temp_sum
left_sum = i
right_sum = j
return (left_sum,right_sum, max_sum)
递归算法
import sys
import math
def find_max_cross_subarray(a, low, mid, high):
left_sum = a[mid]
right_sum = a[mid+1]
left_index = mid
right_index = mid + 1
sum = 0
for i in range(mid, low-1,-1):
sum += a[i]
if sum > left_sum:
left_sum = sum
left_index = i
sum = 0
for i in range(mid+1, high+1, 1):
sum +=a[i]
if sum > right_sum:
right_sum = sum
right_index = i
sum = left_sum + right_sum
return (left_index, right_index, sum)
def find_max_subarray(a, low, high):
#print(str.format('find_max_subarray low={0} high={1}', low, high))
if low == high:
return (low, high, a[low])
mid = math.floor((low + high)/2)
#print(str.format(' divide mid={0}', mid))
cross_low, cross_high, cross_sum = find_max_cross_subarray(a, low, mid, high)
#print(str.format(' left {0} {1}', low, mid))
#print(str.format(' right {0} {1}', mid+1, high))
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)
#print(str.format(' combine mid={0}', mid))
if left_sum >= cross_sum and left_sum >= right_sum:
return (left_low, left_high, left_sum)
elif right_sum >= cross_sum and right_sum >= left_sum:
return right_low, right_high, right_sum
else:
return cross_low, cross_high, cross_sum
if __name__ == '__main__':
'sys.setrecursionlimit(10000)'
a = [-10,-6,-3,-7,-5,-3,-8,-6,-13,-17,-28]
low,high,sum = find_max_subarray(a,0,10)
print((low, high, sum))
4.1-4 假定修改最大子数组问题的定义,允许结果为空子数组,其和为0。你应该知道如何修改现有算法,使它们能允许空子数组为最终结果?
from divideconquar import find_max_subarray
def find_max_subarray_ex(a, low, high):
n = high - low + 1
flag = True
for i in range(0,n,1):
if a[low+i] > 0:
flag = False
break
if flag == True:
return (-1,-1, 0)
return find_max_subarray(a, low, high)
if __name__ == '__main__':
a = [-10, -6, -3, -7, -5, -3, 10, -6, -13, -17, -28]
low, high, sum = find_max_subarray_ex(a, 0, 10)
print((low, high, sum))
4.1-5 使用如下思想为最大子数组问题设计一个非递归的、线性时间的算法。 从数组的左边界开始,由左至右处理,记录到目前为止已经处理过的最大子数组。若已知A[1..j]的最大子数组,基于如下性质将其扩展为A[1..j+1]的最大子数组:A[1..J+1]的最大子数组要么是A[1..j]的最大子数组,要么是某个子数组A[i..j+1](1<=i<=j+1)。在已知A[1..j]最大子数组的情况下,可以在线性时间内找出形如A[i..j+1]的最大子数组。
答:伪代码如下
FIND_MAX_SUBARRAY(a, n)
low = 1
high = 1
sum = A[1]
for j = 2 to n
temp_sum = 0
sum1 = A[j]
low1 = j
high1 = j
for i=j downto 1
temp_sum +=A[i]
if temp_sum > sum1
sum1=temp_sum
low1 = i
if sum1 > sum
sum = sum1
low = low1
high = high1
return (low, high, sum)
本文详细讨论了最大子数组问题,包括当所有元素为负数时的情况,暴力求解的Θ(n²)算法,递归算法的实现,以及如何修改算法以允许空子数组。此外,还介绍了如何设计一个非递归的线性时间算法来解决该问题。

800

被折叠的 条评论
为什么被折叠?



