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
  • 相关阅读:
    BadUSB 利用
    java 将函数作为参数传递
    odoo12 修行提升篇之 常用的高阶函数 (二)
    odoo12 修行提升篇之 异步定时任务 (一)
    odoo12 修行基础篇之 利用kanban做分析 点击跳转分析模型列表 (九)
    odoo12 修行基础篇之 kanban (八)
    odoo12 修行基础篇之 记录批处理 (七)
    odoo12 修行基础篇之 列表的筛选和分组 (六)
    odoo12 修行基础篇之 添加记录编码 (五)
    odoo12 修行基础篇之 添加工作流和操作记录 (四)
  • 原文地址:https://www.cnblogs.com/echoht/p/3710523.html
Copyright © 2011-2022 走看看