脑抽的我上个文章烂尾,又开新坑,,,,我只能对自己前面开的烂坑说一句:青山不改,绿水长流,我们有缘再见!
这次我想刷一刷算法题(对,我又叒叕换目标了),把常见的基础算法做一个总结(千万别又是起个头就扔那里不管了,真的是废人一个了。。。)
好,话不多说,递归(Recursion)走起!
概念理解:
首先我们分析一下定义,递归是一种使用某种函数来解决问题的方法(当然你可以忽略这句废话),特殊之处便在于该函数会不断调用它自身来作为其子程序。
那么,如何实现这么一个函数呢?它调用自己,又是干了些什么呢?
这个小技巧便是该递归函数每一次调用的时候,它都能将给定的问题变成该问题的子问题,该函数会不知疲倦的一直调用它自己(觉得像影分身之术,但是确切点说的话,是那种分身又施展影分身术的 feel...),直到子问题被解决掉,不再产生递归为止(所以说,不是子子孙孙无穷匮哦,递归没有我们的愚公爷爷厉害)。
所以,递归函数是一定存在边界的,也就是终止条件。在遇到某种情况时,递归函数将不再调用自身,而是输出一个结果(当然也可以什么也不输出,直接结束子程序)。所以写递归函数的时候,一定不要忘了写终止递归的条件(个人建议,先写这些边界条件,后面再写程序处理逻辑)~
扯了这么多,脑中挥散不去的还是大家对我爆喊 “talk is cheap, show me the code!"的场景,那么,代码兄,该你登场了(以下题目均来自LeetCode)~
附注:建议大家看看问题3,因为提到了一个递归经常遇到的问题,重复计算,而解决重复计算的方法也很简单,加入一个记忆机制(Memoization),也就是储存我们计算过的值即可。
问题1:字符串翻转,要求,O(1)空间复杂度(看所给的例子输入,题目应该叫列表翻转才更贴切)
例子:
输入: ['a','b','c']
输出: ['c','b','a']
解决思路:
1.取出首尾两个字符,并做交换;
2.递归调用该函数,来翻转剩下的子串。
3.设计跳出递归的边界条件,这里是begin >= end,即字符串遍历完毕。
def reverseString(begin, end,s) -> None:
"""
Do not return anything, modify s in-place instead.
"""
if begin >= end:
return
s[begin], s[end] = s[end], s[begin]
reverseString(begin + 1, end - 1, s)
s = ['a','b','c']
reverseString(0, len(s) - 1, s)
print(s)
### output ###
# ['c', 'b', 'a']
问题2:给定一个链表,每两个相邻的节点交换位置,并返回头节点。
例子:
输入链表:1->2->3->4
输出链表:2->1->4->3
解决思路:
1.交换前两个节点的位置;
2.把剩下的链表传递给自身,递归调用。
3.当抵达链表尾部时结束递归。
class ListNode: #定义节点类
def __init__(self, x):
self.val = x
self.next = None
def swapPairs(head) -> ListNode: #实现功能的递归函数
if head == None or head.next == None:
return head
temp = head.next # 节点2,也就是temp,即为我们所要的head
head.next = swapPairs(temp.next) #将节点1 和后面的链表串拼接,也就是(4->3)
temp.next = head # 将节点2的后面接上节点1
return temp #返回节点2
def printListNode(node): #辅助函数,打印链表
while node:
print(node.val, end=' ')
if node.next:
print('->', end=' ')
node = node.next
print()
if __name__ == '__main__':
head = node = ListNode(1)
for i in range(2,5):
node.next = ListNode(i)
node = node.next
printListNode(head)
ans = swapPairs(head)
printListNode(ans)
问题3:杨辉三角形(听说你不知道什么是杨辉三角形,链接附上,送给各位看官)
杨辉三角形
在讨论这个问题之前,为了让大家看的更清晰,我们先提纲挈领一波,在此讨论一下两个概念,递推关系和边界条件。
递推关系说白了就是问题结果和子问题的结果之间的关系,而边界条件