java debug 模式_2018最全java设计模式精讲 Debug 方式+内存分析(已完结)

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

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

示例 1:

输入: [1,3,null,null,2]

1

/

3

\

2

输出: [3,1,null,null,2]

3

/

1

\

2

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

示例 2:

输入: [3,1,4,null,null,2]

3

/ \

1   4

/

2

输出: [2,1,4,null,null,3]

2

/ \

1   4

/

3

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

进阶:

使用 O(n) 空间复杂度的解法很容易实现。

你能想出一个只使用常数空间的解决方案吗?

解题思路

这个问题非常简单。我们知道二分搜索树的中序遍历是一个单调递增的数组。对于例一来说,输入树的中序遍历是

3 2 1

1

很明显,此时不是递增数组,我们只需要将3和1换一下位置即可。对于例二来说,输入树的中序遍历是

1 3 2 4

1

此时也不是递增数组,我们只需要将2和3换一下位置即可。现在的问题是我们怎么知道要交换哪两个数呢?我们可以对输入的树进行中序遍历,遍历的过程中判断之前访问的节点pre.val是不是大于当前访问的节点cur.val,如果是的话,我们就要记录pre,此时pre就是要交换的第一个元素。然后我们继续遍历,直到再也没有出现pre.val > cur.val的情况了,此时我们最后一次出现的cur就是我们要交换的第二个元素(参考第一个例子)。关于遍历操作,可以参看如下这几篇

Leetcode 144:二叉树的前序遍历(最优雅的解法!!!)

Leetcode 94:二叉树的中序遍历(最优雅的解法!!!)

Leetcode 145:二叉树的后序遍历(最详细的解法!!!

class Solution:

def recoverTree(self, root):

"""

:type root: TreeNode

:rtype: void Do not return anything, modify root in-place instead.

"""

self.pre = None

self.m1, self.m2 = None, None

self.inorderTraversal(root)

self.m1.val, self.m2.val = self.m2.val, self.m1.val

def inorderTraversal(self, root):

if root:

self.inorderTraversal(root.left)

if self.pre != None and self.pre.val > root.val:

if self.m1 == None:

self.m1 = self.pre

self.m2 = root

self.pre = root

self.inorderTraversal(root.right)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

同时我们也可以轻松的写出迭代版本。

class Solution:

def recoverTree(self, root):

"""

:type root: TreeNode

:rtype: void Do not return anything, modify root in-place instead.

"""

cur, pre = root, None

first, second = None, None

stack = []

while cur or stack:

if cur:

stack.append(cur)

cur = cur.left

else:

node = stack.pop()

if pre and pre.val >= node.val:

if not first:

first = pre

second = node

pre = node

cur = node.right

first.val, second.val = second.val, first.val

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

我将该问题的其他语言版本添加到了我的GitHub Leetcode

如有问题,希望大家指出!!!

---------------------

作者:coordinate_blog

来源:CSDN

原文:https://blog.csdn.net/qq_17550379/article/details/85157903

版权声明:本文为博主原创文章,转载请附上博文链接!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值