我正在通过this解决方案来解决最长增加子序列问题,并注意到在运行主函数的驱动程序中重新定义了子序列长度最大值的全局变量以及计算最长子序列的实际函数:
# global variable to store the maximum
global maximum
def _lis(arr , n ):
# to allow the access of global variable
global maximum
# Base Case
if n == 1 :
return 1
# maxEndingHere is the length of LIS ending with arr[n-1]
maxEndingHere = 1
"""Recursively get all LIS ending with arr[0], arr[1]..arr[n-2]
IF arr[n-1] is maller than arr[n-1], and max ending with
arr[n-1] needs to be updated, then update it"""
for i in xrange(1, n):
res = _lis(arr , i)
if arr[i-1] < arr[n-1] and res+1 > maxEndingHere:
maxEndingHere = res +1
# Compare maxEndingHere with overall maximum.And update
# the overall maximum if needed
maximum = max(maximum , maxEndingHere)
return maxEndingHere
def lis(arr):
# to allow the access of global variable
global maximum
# lenght of arr
n = len(arr)
# maximum variable holds the result
maximum = 1
# The function _lis() stores its result in maximum
_lis(arr , n)
return maximum
似乎每次进行递归调用时,都会重置最大值。在函数的局部范围内重新定义全局变量的目的是什么?
答案 0 :(得分:1)
您必须在函数中使用global
关键字才能全局更改变量;如果不使用关键字,它将创建一个具有相同名称的本地范围变量。语句global maximum
不会“重新定义”变量,但它会告诉Python如果在此函数中maximum
设置为某个值,则全局变量将被更改。
In [1]: a = 42
In [2]: def f():
...: a = 23
...:
In [3]: f()
In [4]: a
Out[4]: 42
In [5]: def g():
...: global a
...: a = 23
...:
In [6]: g()
In [7]: a
Out[7]: 23
答案 1 :(得分:1)
查看代码结构:没有递归调用 lis ;当它在第42行初始化maximum = 1时,该仅时间执行此语句。其他所有内容都在 _lis 内完成,其中最大值仅更新,永不重置为1.
我建议您找到其他要学习的代码。这个例子显示了处理变量 maximum 和 arr 的不良习惯 - 作者使用循环式逻辑忽略了递归的强大功能。您可以通过将其升级为易于阅读和维护的程序来进行良好的课堂练习。
在动态编程中,唯一的全局变量应该是memoization。实际上,这个例子使用 no memoization - 这意味着不是动态编程。简而言之,应该有一个备忘录列表,其中memo [n]保存_lis(arr,n)中的值。递归调用不应超过一个深度,因为 _lis 将返回此存储的值。最后的答案只是 max(备忘录)。
请参阅dynamic programming和memoization上的WIkipedia网页。