您可以编写递归函数来接受 3 个参数:迄今为止遇到的第一个和第二个最小值,以及列表的其余部分(您尚未检查)。
然后,通过将列表参数的第一个元素与迄今为止最小的两个元素进行比较,您可以选择 3 个中的哪 2 个作为参数传递到下一个递归。
您需要将此递归函数包装在一个表示函数中,该函数设置并调用递归函数,同时处理元素少于 2 个列表等情况。
def recurse(min1, min2, list):
if len(list)==0:
return min2
first, rest = list[0], list[1:]
if first < min1:
return recurse(first, min1, rest)
if first < min2:
return recurse(min1, first, rest)
return recurse(min1, min2, rest)
def second_smallest(list):
if len(list) < 2:
raise ValueError("too few elements to find second_smallest")
a, b, rest = list[0], list[1], list[2:]
if b < a:
return recurse(b, a, rest)
else:
return recurse(a, b, rest)
这种解决方案并不是特别Pythonic——它更像是一种函数式编程风格。
最后,您可以传递列表前面的参数,并组合这两个函数来获得您正在寻找的解决方案:
def second_smallest(list):
if len(list) < 2:
raise ValueError("too few elements to find second_smallest")
a, b = list[0], list[1]
a, b = min(a,b), max(a,b)
if len(list) == 2:
return b
c, rest = list[2], list[3:]
if c < a:
return second_smallest([c,a]+rest)
if c < b:
return second_smallest([a,c]+rest)
return second_smallest([a,b]+rest)
请注意,此函数做了一些多余的工作,因为它无法知道它是否首先被调用,或者是否递归地调用自身。还,+
创建一个新列表,因此对于大小为 n 的列表,此代码可能需要 O(n^2) 时间。