zoukankan      html  css  js  c++  java
  • [Leetcode] Recover Binary Search Tree

    Recover Binary Search Tree 题解

    题目来源:https://leetcode.com/problems/recover-binary-search-tree/description/


    Description

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

    Recover the tree without changing its structure.

    Note:

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

    Solution

    解法一:使用递归中序遍历找到乱序节点位置

    class Solution {
    private:
        TreeNode *first = nullptr;
        TreeNode *second = nullptr;
        TreeNode *pre = nullptr;
        void traverse(TreeNode *node) {
            if (node) {
                traverse(node -> left);
    
                if (!first && pre -> val >= node -> val)  // first还没有找到,出现乱序
                    first = pre;
                if (first && pre -> val >= node -> val)  // first已经找到,出现乱序
                    second = node;
    
                pre = node;
    
                traverse(node -> right);
            }
        }
    public:
        void recoverTree(TreeNode* root) {
            TreeNode temp(INT_MIN);
            pre = &temp;
    
            traverse(root);
    
            swap(first -> val, second -> val);
        }
    };
    

    解法二:使用Morris中序遍历找到乱序节点位置

    class Solution {
    public:
        void recoverTree(TreeNode* root) {
            TreeNode *first = NULL;
            TreeNode *second = NULL;
            TreeNode *pre = NULL;
            TreeNode *temp = NULL;
            // Morris遍历
            while (root) {
                if (root -> left) {
                    temp = root -> left;
                    while (temp -> right && temp -> right != root) {
                        // 找到左子树的最右节点
                        temp = temp -> right;
                    }
                    if (temp -> right) { // 左子树的最右节点已经连接到pre的左侧
                        if (pre && pre -> val >= root -> val) {
                            if (!first) {
                                first = pre;
                                // 因为可能只存在一个乱序位置,所以要先设置second
                                second = root;
                            } else {
                                second = root;
                            }
                        }
                        // 左子树已经遍历
                        pre = root; // 右子树之前访问的点即为root
                        temp -> right = NULL; // 断开左子树最右侧节点与root的连接
                        root = root -> right; // 切换到右子树进行遍历
                    } else { // 仍未连接到pre,则进行连接
                        temp -> right = root; // 将左子树最右侧节点与root连接
                        root = root -> left; // 左子树还没遍历,切换到左子树进行遍历
                    }
                } else {
                    // 左子树为空的情况
                    if (pre && pre -> val >= root -> val) {
                        if (!first) {
                            first = pre;
                            second = root;
                        } else {
                            second = root;
                        }
                    }
                    // 左子树为空,切换到右子树
                    pre = root; // 右子树之前访问的点即为root
                    root = root -> right; // 切换到右子树进行遍历
                }
            }
            if (first && second)
                swap(first -> val, second -> val);
        }
    };
    

    解题描述

    这道题题意是,给出一棵二叉搜索树,树上有两个节点被交换了位置,要求恢复这棵二叉搜索树。上面给出两种解法,分别是递归中序遍历解法和Morris中序遍历的解法。其中Morris中序遍历是一种非递归的树遍历方式,并且不需要借助队列或者栈等数据结构,具有常数空间复杂度。

  • 相关阅读:
    struts1与struts2的差别
    UVA 1563
    项目开发相关规范
    互联网产品的測试
    虚拟机器人
    Caused by: java.lang.ClassNotFoundException: org.hibernate.annotations.common.reflection.MetadataPro
    HDU 1429--胜利大逃亡(续)【BFS && 状态压缩】
    自己写的php curl库实现整站克隆
    设置字符串中某些字符的特殊效果
    Objective-C学习笔记(二十二)——初始化方法init的重写与自己定义
  • 原文地址:https://www.cnblogs.com/yanhewu/p/8456794.html
Copyright © 2011-2022 走看看