Python算法-递归(Recrusion)

递归-4个要素

  • 1 接收的参数
  • 2 返回值
  • 3 终止的条件
  • 4 递归拆解:如何递归到下一层

509:斐波拉契数列
f(n) = f(n-1) + f(n-2)
f(0) =0; f(1) = 1

class Solution:
    def fib(self, n: int) -> int:
        if n < 2:               # 终止条件
            return n 
        return self.fib(n-1) + self.fib(n-2)

206:反转链表
输入:1->2->3->4->5->NULL
输出:5->4->3->2->1->NULL

### 使用递归
class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        if not head or not head.next:
            return head
        p = self.reverseList(head.next)
        head.next.next = head       # 两元素链表反向
        head.next = None
        return p

344:反转字符串
输入:['h','e','l','l']
输出:['l','l','e','h']

# 方法1: 双指针
def doublePoint(s):
    left = 0
    right = len(s) - 1
    while left < right:
        s[left], s[right] = s[right], s[left]       # 原地交换
        left += 1       # 左指针右移
        right -= 1      # 右指针左移
    return s
s = ['h','e','l','l']
print(doublePoint(s))
# 方法2:递归+双指针
def reverseList1(s):
    left = 0
    right = len(s) - 1
    if s == None or len(s) == 0:
        return  
    recursion(s, left, right)
    return s

def recursion(s, left, right):
    if left >= right:
        return
    recursion(s, left+1, right-1)
    s[left], s[right] = s[right], s[left]

s = ['h','e','l','l']
# print(reverseList1(s))

二叉树的最大深度

数据结构

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
  • 方法1:从上到下计算(前序遍历)-深度优先搜索

1 从根节点开始,每下降一层,就将深度 +1
2 用全局变量来纪录下最大深度
3 每当达到叶子节点时就与全局变量进行比较和更新

class Solution:
    def maxDepth(self, root: TreeNode) -> int:
        def dfs(res, root):
            # 叶子节点为空,递归结束
            if root == None:
                return res
            else:
                res += 1
            left_height = dfs(res, root.left)  #
            right_height = dfs(res, root.right)
            return max(left_height, right_height)
        # 初始高度为0
        res = dfs(0, root)
        return res
  • 方法2:从下到上计算(后序遍历)深度优先搜索-dfs

思路:已知左子树和右子树的最大深度为 l 和 r, 该二叉树的最大深度为
max_depth = max(l, r) + 1
递归不断分解二叉树

class Solution:
    def maxDepth(self, root: TreeNode) -> int:
        return self.dfs(root)
    
    def dfs(self, root):
        # 如果是空节点,则深度为 0 
        if root == None:
            return 0
        # 遍历得到左右子树的最大深度
        left_height = self.dfs(root.left)
        right_height = self.dfs(root.right)
        # 返回左右子树的最大深度,再加上根节点的深度
        return max(left_height, right_height) + 1
  • 方法3:层序遍历-广度优先搜索

1 使用队列来存放节点
2 一开始先知道当前层数的节点个数,然后根据个数出队,并对其孩子节点入队

class Solution:
    def maxDepth(self, root: TreeNode) -> int:
        if root == None:
            return 0
        deque = [root]
        res = 0
        while deque:
            # 层数
            res += 1
            # 找到当前层的节点数
            length = len(deque)
            # 依次取出当前层的节点
            for i in range(length):
                tmpNode = deque.pop(0)
                # 查找左右子树
                if tmpNode.left:
                    deque.append(tmpNode.left)
                if tmpNode.right:
                    deque.append(tmpNode.right)
        return res
62-不同路径
  • 动态规划
# class Solution:
#     def uniquePaths(self, m: int, n: int) -> int:
        # dp = [[0 for i in range(n)] for j in range(m)]
        # 第一种写法
        dp[0][0] = 1
        for i in range(m):
            for j in range(n):
                # 左边有有效值
                if i-1 >= 0 and i-1 < m:
                    dp[i][j] = dp[i][j] + dp[i-1][j]
                # 右边有有效值
                if j-1 >= 0 and j-1 < n:
                    dp[i][j] = dp[i][j] + dp[i][j-1]
        return dp[m-1][n-1]

        # 第二种写法
        for i in range(m):
            dp[i][0] = 1
        for j in range(n):
            dp[0][j] = 1
        
        for i in range(1, m):
            for j in range(1, n):
                dp[i][j] = dp[i-1][j] + dp[i][j-1]
        return dp[m-1][n-1]
  • 动态规划优化
class Solution:
    def uniquePaths(self, m: int, n: int) -> int:
        dp = [0]*n
        for i in range(n):
            dp[i] = 1
        for i in range(1, m):
            dp[0] = 1
            for j in range(1, n):
                dp[j] = dp[j-1] + dp[j]
                
        return dp[n-1]
  • 方法2:递归写法

1 递归关系式:dfs(i,j) = dfs(i-1, j) + dfs(i, j-1)
2 找出初始值:如果i或者j有一个为0,那么不能使用关系式

class Solution:
    def uniquePaths(self, m: int, n: int) -> int:
        arr = [[0 for i in range(n)] for j in range(m)]
        return self.dfs(m-1, n-1, arr)
    
    def dfs(self, i, j, arr):
        if i == 0 or j == 0:
            return 1
        if arr[i][j] != 0:
            return arr[i][j]
        arr[i][j] = self.dfs(i-1, j, arr) + self.dfs(i, j-1, arr)
        return arr[i][j]

快速幂

class Solution:
    def myPow(self, x: float, n: int) -> float:
        if x == 0:
            return 0
        res = 1
        if n < 0:
            x = 1/x
            n = -n
        while n > 0:
            if n & 1 == 1:
                res *= x
            x *= x
            n = n >> 1
        return res
  • 递归算法
        # 递归算法
        if x == 0:
            return 0
        if n < 0:
            x = 1/x
            n = -n
        return self.quitPow(x, n)

    def quitPow(self, x, n):
        if n == 0:
            return 1
        if (n & 1) == 1:
            return x*self.quitPow(x*x, n>>1)
        return self.quitPow(x*x, n>>1)
寻找两个正序数组的中位数
  • 排序法
class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        if nums1 == None and nums2 == None:
            return None

        num = nums1 + nums2
        num.sort()
        length = len(num)
        if length % 2 == 0:
            res = (num[length//2-1] + num[length//2])/2
        else:
            res = num[length//2]
        return res

你可能感兴趣的:(Python算法-递归(Recrusion))