美文网首页
Python算法-递归(Recrusion)

Python算法-递归(Recrusion)

作者: ShowMeCoding | 来源:发表于2021-09-01 16:09 被阅读0次

    递归-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)

          本文链接:https://www.haomeiwen.com/subject/imuzvltx.html