背景

本篇图文是LSGO软件技术团队组织的 第二期基础算法(Leetcode)刻意练习训练营 的打卡任务。本期训练营采用分类别练习的模式,即选择了五个知识点(数组、链表、字符串、树、贪心算法),每个知识点选择了 三个简单、两个中等、一个困难 等级的题目,共计三十道题,利用三十天的时间完成这组刻意练习。

本次任务的知识点:树

是一种抽象数据类型(ADT)或是实现这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合。它是由 n(n>0) 个有限节点组成的一个具有层次关系的集合。

把它叫做「树」是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。

它具有以下的特点:

  • 每个节点都只有有限个子节点或无子节点;
  • 没有父节点的节点称为根节点;
  • 每一个非根节点有且只有一个父节点;
  • 除了根节点外,每个子节点可以分为多个不相交的子树;
  • 树里面没有环路。

题目

  • 题号:99
  • 难度:困难
  • https://leetcode-cn.com/problems/recover-binary-search-tree/

二叉搜索树中的两个节点被错误地交换。

请在不改变其结构的情况下,恢复这棵树。

示例 1:

输入: [1,3,null,null,2]1/3\2输出: [3,1,null,null,2]3/1\2

示例 2:

输入: [3,1,4,null,null,2]3/ \
1   4/2输出: [2,1,4,null,null,3]2/ \
1   4/3

进阶:

  • 使用 O(n) 空间复杂度的解法很容易实现。
  • 你能想出一个只使用常数空间的解决方案吗?

实现

第一种:利用中序遍历

二叉搜索树是左孩子小于根节点,右孩子大于根节点的树,所以做一次中序遍历,产生的序列就是从小到大排列的有序序列。

回到这道题,题目交换了两个数字,其实就是在有序序列中交换了两个数字。而我们只需要把它还原。

交换位置有两种情况:

  • 相邻的两个数字交换

[ 1 2 3 4 5 ] 中 2 和 3 进行交换,[ 1 3 2 4 5 ],这样的话只产生一组逆序的数字(正常情况是从小到大排序,交换后产生了从大到小),3 2。

我们只需要遍历数组,找到后,把这一组的两个数字进行交换即可。

  • 不相邻的两个数字交换

[ 1 2 3 4 5 ] 中 2 和 5 进行交换,[ 1 5 3 4 2 ],这样的话其实就是产生了两组逆序的数字对。5 3 和 4 2。

所以我们只需要遍历数组,然后找到这两组逆序对,然后把第一组前一个数字和第二组后一个数字进行交换即完成了还原。

综上,在中序遍历中,只需要利用一个 pre 节点和当前节点比较,如果 pre 节点的值大于当前节点的值,那么就是我们要找的逆序的数字。分别用两个指针 first 和 second 保存即可。如果找到第二组逆序的数字,我们就把 second 更新为当前节点。最后把 first 和 second 两个的数字交换即可。

  • 执行结果:通过
  • 执行用时:132 ms, 在所有 C# 提交中击败了 72.41% 的用户
  • 内存消耗:27.6 MB, 在所有 C# 提交中击败了 100.00% 的用户
/*** Definition for a binary tree node.* public class TreeNode {*     public int val;*     public TreeNode left;*     public TreeNode right;*     public TreeNode(int x) { val = x; }* }*/
public class Solution
{public void RecoverTree(TreeNode root){inorderTraversal(root);if(first == null || second == null)return;int temp = first.val;first.val = second.val;second.val = temp;}private TreeNode pre = null;private TreeNode first = null;private TreeNode second = null;private void inorderTraversal(TreeNode root){if (root == null){return;}inorderTraversal(root.left);if (pre != null && pre.val > root.val){//第一次遇到逆序对if (first == null){first = pre;second = root;}else{//第二次遇到逆序对second = root;}}else{pre = root;}inorderTraversal(root.right);}
}

Python 语言

  • 执行结果:通过
  • 执行用时:64 ms, 在所有 Python3 提交中击败了 93.67% 的用户
  • 内存消耗:14 MB, 在所有 Python3 提交中击败了 5.32% 的用户
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = Noneclass Solution:def recoverTree(self, root: TreeNode) -> None:"""Do not return anything, modify root in-place instead."""self.inorderTraversal(root)if self.first is None or self.second is None:return Noneself.first.val, self.second.val = self.second.val, self.first.valdef __init__(self):self.pre = Noneself.first = Noneself.second = Nonedef inorderTraversal(self, root: TreeNode) -> None:if root is None:return Noneself.inorderTraversal(root.left)if self.pre is not None and self.pre.val > root.val:if self.first is None:self.first = self.preself.second = rootelse:self.second = rootelse:self.pre = rootself.inorderTraversal(root.right)

往期活动

LSGO软件技术团队会定期开展提升编程技能的刻意练习活动,希望大家能够参与进来一起刻意练习,一起学习进步!

  • Python基础刻意练习活动即将开启,你参加吗?
  • Task01:变量、运算符与数据类型
  • Task02:条件与循环
  • Task03:列表与元组
  • Task04:字符串与序列
  • Task05:函数与Lambda表达式
  • Task06:字典与集合
  • Task07:文件与文件系统
  • Task08:异常处理
  • Task09:else 与 with 语句
  • Task10:类与对象
  • Task11:魔法方法
  • Task12:模块

我是 终身学习者“老马”,一个长期践行“结伴式学习”理念的 中年大叔

我崇尚分享,渴望成长,于2010年创立了“LSGO软件技术团队”,并加入了国内著名的开源组织“Datawhale”,也是“Dre@mtech”、“智能机器人研究中心”和“大数据与哲学社会科学实验室”的一员。

愿我们一起学习,一起进步,相互陪伴,共同成长。

后台回复「搜搜搜」,随机获取电子资源!
欢迎关注,请扫描二维码:

刻意练习:LeetCode实战 -- Task24. 恢复二叉搜索树相关推荐

  1. 刻意练习:LeetCode实战 -- 不同的二叉搜索树

    背景 今天,第二期基础算法(Leetcode)刻意练习训练营 的打卡任务是"不同的二叉搜索树 II",而LeetCode也有"不同的二叉搜索树"题目,故一起写了 ...

  2. 二叉搜索树的中序遍历为 递增序列_Go 刷 Leetcode 系列:恢复二叉搜索树

    二叉搜索树中的两个节点被错误地交换. 请在不改变其结构的情况下,恢复这棵树. 示例 1: 输入: [1,3,null,null,2] 1 / 3 \ 2输出: [3,1,null,null,2] 3 ...

  3. LeetCode 98验证二叉搜素树(中序遍历)99恢复二叉搜索树

    微信搜一搜:bigsai 大家都在关注的刷题.学习数据结构和算法宝藏项目 关注回复进群即可加入力扣打卡群,欢迎划水.近期打卡: LeetCode 92反转链表Ⅱ&93复制ip地址&94 ...

  4. LeetCode 95. 不同的二叉搜索树 II(递归)

    1. 题目 给定一个整数 n,生成所有由 1 - n 为节点所组成的二叉搜索树. 示例: 输入: 3 输出: [[1,null,3,2],[3,2,null,1],[3,1,null,null,2], ...

  5. LeetCode 96. 不同的二叉搜索树(DP)

    1. 题目 给定一个整数 n,求以 1 - n 为节点组成的二叉搜索树有多少种? 示例:输入: 3 输出: 5 解释: 给定 n = 3, 一共有 5 种不同结构的二叉搜索树:1 3 3 2 1\ / ...

  6. Leetcode 96. 不同的二叉搜索树

    Leetcode 96. 不同的二叉搜索树 1.问题分析 2.问题解决 3.总结 1.问题分析 题目链接:https://leetcode-cn.com/problems/unique-binary- ...

  7. 72. Leetcode 99. 恢复二叉搜索树 (二叉搜索树-中序遍历类)

    给你二叉搜索树的根节点 root ,该树中的 恰好 两个节点的值被错误地交换.请在不改变其结构的情况下,恢复这棵树 .示例 1:输入:root = [1,3,null,null,2] 输出:[3,1, ...

  8. [Leetcode][第99题][JAVA][恢复二叉搜索树][中序遍历]

    [问题描述][困难] [解答思路] 1. 显示中序遍历 时间复杂度:O(N) 空间复杂度:O(N) class Solution {public void recoverTree(TreeNode r ...

  9. 恢复二叉搜索树Python解法

    给你二叉搜索树的根节点 root ,该树中的 恰好 两个节点的值被错误地交换.请在不改变其结构的情况下,恢复这棵树 . 来源:力扣(LeetCode) 链接:https://leetcode-cn.c ...

最新文章

  1. Kotlin functions
  2. php绑定邮箱地址链接,php完美匹配邮箱、链接地址和电话号码
  3. 关于如何在Nomad中保护工作部署的工作流的简要历史
  4. 微服务网关Gateway实现Host过滤
  5. PHP中 .= 的意思
  6. DNS 正向查找与反向查找
  7. dto与java bean_POJO、JavaBean、DTO的区别
  8. 计算机应用怎么写,计算机应用专业描述怎么写
  9. crio电压采集 labview_LabVIEW与cRIO入门.pdf
  10. 山地车中轴进水表现_4种自行车中轴的拆卸和保养方法
  11. 网站服务器会把手机拉黑吗,怎么知道对方手机把我拉黑了
  12. 算法提高 盾神与积木游戏
  13. 用html计算长方形的面积公式,【长方形正方形的面积计算公式】《长方形、正方形的面积计算》优秀教学反思...
  14. Kafka SASL配置 Demo测试
  15. 伤感日志_茫茫天涯走遍,寂寞心酸
  16. C++检测键盘大小写
  17. 如何升级Vue的版本 vue2.9.6升级到vue3.0
  18. 5.zookeeper集成Java项目curator客户端
  19. UI库你应该知道的基础(超实用)
  20. 医疗器械标准目录 第二部分专业技术领域(2)

热门文章

  1. 1069 The Black Hole of Numbers
  2. 1093 Count PAT‘s
  3. IDEA IntelliJ 如何设置网站的欢迎页面
  4. html中item属性,项目id(属性) | itemid (attribute)
  5. ps aux|grep
  6. Database Appliance并非Mini版的Exadata-还原真实的Oracle Unbreakable Database Appliance
  7. Linux之 手动释放内存
  8. 在visual studio 2010中调用ffmpeg
  9. Linq to SQL 资源
  10. 一个系统的html源代码,h5后台模板源码bootstrap网站后台管理系统HTML页面后台源代码...