美文网首页算法学习
算法题--修正只有2个元素错置的二叉搜索树

算法题--修正只有2个元素错置的二叉搜索树

作者: 岁月如歌2020 | 来源:发表于2020-04-27 23:06 被阅读0次
    image.png

    0. 链接

    题目链接

    1. 题目

    Two elements of a binary search tree (BST) are swapped by mistake.

    Recover the tree without changing its structure.

    Example 1:

    Input: [1,3,null,null,2]
    
       1
      /
     3
      \
       2
    
    Output: [3,1,null,null,2]
    
       3
      /
     1
      \
       2
    

    Example 2:

    Input: [3,1,4,null,null,2]
    
      3
     / \
    1   4
       /
      2
    
    Output: [2,1,4,null,null,3]
    
      2
     / \
    1   4
       /
      3
    

    Follow up:

    A solution using O(n) space is pretty straight forward.
    Could you devise a constant space solution?

    2. 思路1: Morris中序遍历

    1. 建立螺纹二叉树(Threaded Binary Tree), 即满足下列两个要求:
    • 1.1 所有原本为空的右子节点指向中序遍历顺序之后的那个节点;
    • 1.2 所有原本为空的左子节点指向中序遍历顺序之前的那个节点

    具体实现过程:

    (1) 初始化指针cur指向root
    (2) 当cur不为空时
        -- 如果cur没有左子节点, 说明找到了目前未遍历到的部分的最小值,则
            a) 得到一个中序遍历的元素cur.val
            b) 将cur指向其右子节点(可理解为目前未遍历到的最靠左的那个树的右子节点, 变成了最新的最左端)
        -- 否则
            将pre指针指向cur的左子树中的最右子节点, 不能指向cur(目的是实现1.1的要求)
            ** 若pre的右子节点为空, 说明找到了1.1要求的那个节点, 则
                a) 将pre的右子节点指向cur
                b) 将cur指向cur.left
            ** 否则
                a) 将pre的右子节点置空
                b) 得到一个中序遍历的元素cur.val
                c) 将cur指向其右子节点
                
    
    1. 对于合法的二叉搜索树而言,
    • 进行中序遍历后得到的应该是一个升序排列的数组, 利用这个特性,在遍历的过程中,用比较前一个得到的值跟当前值,若last_element.val >= cur.val, 则说明至少发现了一个嫌疑点, 用first_element记录此时的last_element, 用second_element记录此时的cur节点;若后续又发现了这种情况的存在, 则更新second_element
    • 交换first_elementsecond_elementval即可.

    3. 代码

    # coding:utf8
    
    
    # Definition for a binary tree node.
    class TreeNode:
        def __init__(self, x):
            self.val = x
            self.left = None
            self.right = None
    
    
    class Solution:
        def recoverTree(self, root: TreeNode) -> None:
            """
            Do not return anything, modify root in-place instead.
            """
            first_element = second_element = None
            cur = root
            last_node = None
            while cur is not None:
                if cur.left is None:
                    if last_node is not None and cur.val <= last_node.val:
                        if first_element is None:
                            first_element = last_node
                            second_element = cur
                        else:
                            second_element = cur
                    last_node = cur
                    cur = cur.right
                else:
                    pre = cur.left
                    while pre.right is not None and pre.right != cur:
                        pre = pre.right
                    if pre.right is None:
                        pre.right = cur
                        cur = cur.left
                    else:
                        pre.right = None
                        if last_node is not None and cur.val <= last_node.val:
                            if first_element is None:
                                first_element = last_node
                                second_element = cur
                            else:
                                second_element = cur
                        last_node = cur
                        cur = cur.right
    
            temp = first_element.val
            first_element.val = second_element.val
            second_element.val = temp
    
    
    def pre_order_traverse(root, array):
        if root is None:
            array.append(None)
            return
        array.append(root.val)
        pre_order_traverse(root.left, array)
        pre_order_traverse(root.right, array)
    
    
    def print_tree(root):
        results = list()
        pre_order_traverse(root, results)
        print(results)
    
    
    root1 = node = TreeNode(1)
    node.left = TreeNode(3)
    node.left.right = TreeNode(2)
    
    root2 = node = TreeNode(4)
    node.left = TreeNode(6)
    node.right = TreeNode(2)
    node.left.right = TreeNode(3)
    node.right.left = TreeNode(5)
    
    root3 = node = TreeNode(3)
    node.left = TreeNode(1)
    node.right = TreeNode(4)
    node.right.left = TreeNode(2)
    
    solution = Solution()
    
    print_tree(root1)
    solution.recoverTree(root1)
    print_tree(root1)
    print('=' * 50)
    print('')
    
    print_tree(root2)
    solution.recoverTree(root2)
    print_tree(root2)
    print('=' * 50)
    print('')
    
    print_tree(root3)
    solution.recoverTree(root3)
    print_tree(root3)
    print('=' * 50)
    print('')
    
    
    

    输出结果

    [1, 3, None, 2, None, None, None]
    [3, 1, None, 2, None, None, None]
    ==================================================
    
    [4, 6, None, 3, None, None, 2, 5, None, None, None]
    [4, 2, None, 3, None, None, 6, 5, None, None, None]
    ==================================================
    
    [3, 1, None, None, 4, 2, None, None, None]
    [2, 1, None, None, 4, 3, None, None, None]
    ==================================================
    
    

    结果

    image.png

    相关文章

      网友评论

        本文标题:算法题--修正只有2个元素错置的二叉搜索树

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