zoukankan      html  css  js  c++  java
  • LeetCode OJ

    这道题要求空间复杂度为O(1),则只能采用Morris Traversal进行中序遍历!!这个了解了之后,难点在于如何定位到两个被交换了的节点?

    我就被困在这里几个小时!!!(允许我为自己的愚蠢表示下悲伤吧!!!)

    参考了discuss中前辈的算法,才发现很简单!!!

    我们只需要这样来看问题,BST的中序遍历是递增的,如果有一对节点被交换了,那么这个递增序列会在被交换的这对节点前后被打破。这一对节点有两种情况:一种是相邻着的,一种是不相邻的。对于第一种情况,我们只会遇到一次顺序被打破;而对于第二种情况,我们会遇到两次顺序被打破。当我们第一次遇到顺序被打破的时候,是中序遍历过程中上次被输出的节点和当前节点的值不满足小于的关系,而且可以肯定得是被交换的节点之一是上次被输出的节点,如果我们将不再遇到第二次顺序被打破,则说明是情况一,并且被交换的另一个节点是当前节点;如果我们会遇到第二次顺序被打破,同样这次也是中序遍历过程中上次被输出的节点和当前节点的值不满足小于的关系,并且可以肯定的是被交换的另一个节点是当前节点。

    通过上述过程可以确定被交换的两个节点,最后再互换这两个节点的值就可以了!!

     1 /**
     2      * Two elements of a binary search tree (BST) are swapped by mistake.
     3      * Recover the tree without changing its structure.
     4      * Could you devise a constant space solution?
     5      * using Morris Traversal
     6      * @param root
     7      */
     8     public void recoverTree(TreeNode root){
     9         if(root == null || root.left == null && root.right == null)
    10             return ;
    11         TreeNode pred1=null ;
    12         TreeNode cur1=null ;
    13         TreeNode pred2=null ;
    14         TreeNode cur2=null ;
    15         
    16         TreeNode cur = root;
    17         TreeNode last = null; // the last node that be printed out
    18         
    19         while(cur!=null){
    20         
    21             if(cur.left!=null){
    22                 //find its predecessor
    23                 TreeNode pre = cur.left;
    24                 while(pre.right!=null && pre.right != cur){
    25                     pre = pre.right;
    26                 }
    27                 if(pre.right == null)
    28                 {
    29                     pre.right = cur;//make the predecessor's right pointer points to the current node
    30                     cur = cur.left;
    31                 }else
    32                 {
    33                     pre.right = null;//recover the predecessor's right pointer.
    34                     last = cur;
    35                     cur = cur.right;// notice here!!!!!!
    36                 }                
    37                 
    38             }else{
    39                 last = cur;
    40                 cur = cur.right;
    41             }
    42             //it's a very nice method!!!!
    43             if(last!=null && cur != null && last.val>cur.val){
    44                 if(pred1 == null){
    45                     pred1 = last;
    46                     cur1 = cur;
    47                 }else
    48                 {
    49                     pred2 = last;
    50                     cur2 = cur;
    51                 }
    52             }
    53         }
    54         
    55         int temp ;
    56         if(pred1 != null && cur2 !=null){
    57             temp = pred1.val;
    58             pred1.val = cur2.val;
    59             cur2.val = temp;
    60         }else{
    61             temp = pred1.val;
    62             pred1.val = cur1.val;
    63             cur1.val = temp;
    64         }
    65         
    66     }
    有问题可以和我联系,bettyting2010#163 dot com
  • 相关阅读:
    Serverless 解惑——函数计算如何访问 MySQL 数据库
    Kubernetes 会不会“杀死” DevOps?
    开发函数计算的正确姿势——使用交互模式安装依赖
    从零开始入门 K8s | 调度器的调度流程和算法介绍
    eclipse中如何自动生成构造函数
    微服务架构中API网关的角色
    JAVA设计模式之责任链模式
    谦先生的程序员日志之我的hadoop大数据生涯一
    谦先生的bug日志之hive启动权限问题
    CSS盒子模型之详解
  • 原文地址:https://www.cnblogs.com/echoht/p/3710523.html
Copyright © 2011-2022 走看看