Python算法题集_翻转二叉树

本文为Python算法题集之一的代码示例

题226:翻转二叉树

1. 示例说明

  • 示例 1:

    在这里插入图片描述

    输入:root = [4,2,7,1,3,6,9]
    输出:[4,7,2,9,6,3,1]
    

    示例 2:

    在这里插入图片描述

    输入:root = [2,1,3]
    输出:[2,3,1]
    

    示例 3:

    输入:root = []
    输出:[]
    

    提示:

    • 树中节点数目范围在 [0, 100]
    • -100 <= Node.val <= 100

2. 题目解析

- 题意分解

  1. 本题为二叉树的翻转
  2. 基本的设计思路是深度优先算法【DFS(Depth-First Search)】、广度有限算法【BFS(Breadth-First Search)】

- 优化思路

  1. 通常优化:减少循环层次

  2. 通常优化:增加分支,减少计算集

  3. 通常优化:采用内置算法来提升计算速度

  4. 分析题目特点,分析最优解

    1. 可以考虑采用迭代法改写递归函数,提高性能

- 测量工具

  • 本地化测试说明:LeetCode网站测试运行时数据波动很大,因此需要本地化测试解决这个问题
  • CheckFuncPerf(本地化函数用时和内存占用测试模块)已上传到CSDN,地址:Python算法题集_检测函数用时和内存占用的模块
  • 本题本地化超时测试用例自己生成,详见【最优算法章节】

3. 代码展开

1) 标准求解【DFS递归】

采用深度优先算法,标准递归实现

马马虎虎,超过66%在这里插入图片描述

import CheckFuncPerf as cfp

class Solution:
 def invertTree_base(self, root):
     if not root:
         return None
     root.left, root.right = root.right, root.left
     self.invertTree_base(root.left)
     self.invertTree_base(root.right)
     return root

aroot = generate_binary_tree(ilen)
aSolution = Solution()
result = cfp.getTimeMemoryStr(Solution.invertTree_base, aSolution, aroot)
print(result['msg'], '执行结果 = {}'.format(result['result'].val))

# 运行结果
函数 invertTree_base 的运行时间为 600.12 ms;内存使用量为 4.00 KB 执行结果 = 71

2) 改进版一【BFS迭代,节点循环】

通过堆栈结构的迭代算法来改写递归算法,单次循环一个节点

性能良好,超过82%在这里插入图片描述

import CheckFuncPerf as cfp

class Solution:
 def invertTree_ext1(self, root):
     if not root:
         return None
     stacktree = [root]
     while stacktree:
         tmpnode = stacktree.pop()
         tmpnode.left, tmpnode.right = tmpnode.right, tmpnode.left
         if tmpnode.right:
             stacktree.append(tmpnode.right)
         if tmpnode.left:
             stacktree.append(tmpnode.left)
     return root

aroot = generate_binary_tree(ilen)
aSolution = Solution()
result = cfp.getTimeMemoryStr(Solution.invertTree_ext1, aSolution, aroot)
print(result['msg'], '执行结果 = {}'.format(result['result'].val))

# 运行结果
函数 invertTree_ext1 的运行时间为 546.13 ms;内存使用量为 0.00 KB 执行结果 = 7

3) 改进版二【BFS迭代,列表循环】

通过队列结构的迭代算法来改写递归算法,每次循环一个批次,减少了部分循环判断计算

勉强通关,超过19%在这里插入图片描述

import CheckFuncPerf as cfp

class Solution:
 def invertTree_ext2(self, root):
     if not root:
         return None
     queueTree = [root]
     while queueTree:
         for iIdx in range(len(queueTree)):
             tmpnode = queueTree.pop()
             tmpnode.left, tmpnode.right = tmpnode.right, tmpnode.left
             if tmpnode.left:
                 queueTree.append(tmpnode.left)
             if tmpnode.right:
                 queueTree.append(tmpnode.right)
     return root

aroot = generate_binary_tree(ilen)
aSolution = Solution()
result = cfp.getTimeMemoryStr(Solution.invertTree_ext2, aSolution, aroot)
print(result['msg'], '执行结果 = {}'.format(result['result'].val))

# 运行结果
函数 invertTree_ext2 的运行时间为 471.11 ms;内存使用量为 0.00 KB 执行结果 = 21

4. 最优算法

根据本地日志分析,最优算法为第3种方式【BFS迭代,列表循环】inorderTraversal_ext2

import random
ilen = 1000000
def generate_binary_tree(node_count):
    if node_count <= 0:
        return None
    root = TreeNode(random.randint(1, 100))
    left = generate_binary_tree(node_count // 2)
    right = generate_binary_tree(node_count // 2)
    root.left = left
    root.right = right
    return root
aroot = generate_binary_tree(ilen)
aSolution = Solution()
result = cfp.getTimeMemoryStr(Solution.invertTree_base, aSolution, aroot)
print(result['msg'], '执行结果 = {}'.format(result['result'].val))
aroot = generate_binary_tree(ilen)
result = cfp.getTimeMemoryStr(Solution.invertTree_ext1, aSolution, aroot)
print(result['msg'], '执行结果 = {}'.format(result['result'].val))
aroot = generate_binary_tree(ilen)
result = cfp.getTimeMemoryStr(Solution.invertTree_ext2, aSolution, aroot)
print(result['msg'], '执行结果 = {}'.format(result['result'].val))

# 算法本地速度实测比较
函数 invertTree_base 的运行时间为 600.12 ms;内存使用量为 4.00 KB 执行结果 = 71
函数 invertTree_ext1 的运行时间为 546.13 ms;内存使用量为 0.00 KB 执行结果 = 7
函数 invertTree_ext2 的运行时间为 471.11 ms;内存使用量为 0.00 KB 执行结果 = 21

一日练,一日功,一日不练十日空

may the odds be ever in your favor ~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

长孤秋落

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值