zoukankan      html  css  js  c++  java
  • 99_恢复二叉搜索树

    99_恢复二叉搜索树

    package 二叉树.二叉搜索树;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * https://leetcode-cn.com/problems/recover-binary-search-tree/
     * 
     * @author Huangyujun
     *
     */
    public class _99_恢复二叉搜索树 {
        // 恢复:即更改有问题的两个结点后,调整整棵树
        //方式1 :先中序遍历将有序的元素存放到容器里,然后遍历容器找出两个有问题的结点。
        //套路:要从出题人角度出发,为啥他要给你一个二叉搜索树~【因为中序遍历比较有特点,整个树也非常有特点,都是 根大于左子树, 小于右子树】
        // 套路:给你一棵二叉搜索树,第一反应(二叉搜索树特点:左子树小于根,右子树大于根,然后中序遍历是递增)
        class Solution {
            public void recoverTree(TreeNode root) {
                List<TreeNode> list = new ArrayList<TreeNode>();
                dfs(root,list);
                TreeNode x = null;
                TreeNode y = null;
                //扫描 list的结果,找出可能存在错误交换的节点x和y【利用升序,第一个错误结点:是出现递减的前一个【突然变大,导致后边那个结点受到影响,与之关系的递增被破坏】,第二个错误结点,是出现递减的后一个【突然变小,导致前边一个结点受到影响,与之关系的递增被破坏】】
                for(int i=0;i<list.size()-1;++i) {
                    if(list.get(i).val>list.get(i+1).val) {
                        y = list.get(i+1);
                        if(x==null) {
                            x = list.get(i);
                        }
                    }
                }
                //如果x和y不为空,则交换这两个节点值,恢复二叉搜索树
                if(x!=null && y!=null) {
                    int tmp = x.val;
                    x.val = y.val;
                    y.val = tmp;
                }
            }
    
            //中序遍历二叉树,并将遍历的结果保存到list中        
            private void dfs(TreeNode node,List<TreeNode> list) {
                if(node==null) {
                    return;
                }
                dfs(node.left,list);
                list.add(node);
                dfs(node.right,list);
            }
        }
        
        //方法2:迭代遍历(其实是第一种方法的简单优化一下而已,将第一种方法的中序递归改成中序迭代,将第一种存储数据元素于容器list,再找到问题结点优化成直接找,标记出两个问题结点,然后进行交换)
        //思路是 中序遍历记录时直接标记出两个有错误的结点【然后再进行交换,就不用把数据都放到容器里,然后遍历容器里的元素后才标出来有问题的元素】
        class Solution3 {
            //用两个变量x,y来记录需要交换的节点
            private TreeNode x = null;
            private TreeNode y = null;
            private TreeNode pre = null;
            public void recoverTree(TreeNode root) {
                dfs(root);
                //如果x和y都不为空,说明二叉搜索树出现错误的节点,将其交换
                if(x!=null && y!=null) {
                    int tmp = x.val;
                    x.val = y.val;
                    y.val = tmp;
                }
            }
            
            //中序遍历二叉树,并比较上一个节点(pre)和当前节点的值,如果pre的值大于当前节点值,则记录下这两个节点
            private void dfs(TreeNode node) {
                if(node==null) {
                    return;
                }
                dfs(node.left);
                if(pre==null) {
                    pre = node;
                }
                else {
                    if(pre.val>node.val) {
                        y = node;
                        if(x==null) {
                            x = pre;
                        }
                    }
                    pre = node;
                }
                dfs(node.right);
            }
        }
    
    
    }

    本文来自博客园,作者:一乐乐,转载请注明原文链接:https://www.cnblogs.com/shan333/p/15709296.html

  • 相关阅读:
    怎样使用jlink一键烧录整个flash Hi3518 a c e Hi3515 Hi3512
    阅读zepto.js的core中的Core methods
    linux下执行strlwr函数出错:ld returned 1 exit status
    POJ 3286 How many 0&#39;s?
    As long as Binbin loves Sangsang
    docker 的安装
    浅析JAVA设计模式之工厂模式(一)
    怎样在屏幕上显示多个alv
    链表的应用:单元多项式的加法、减法、乘法
    Android 开发中 iBeacon的使用
  • 原文地址:https://www.cnblogs.com/shan333/p/15709296.html
Copyright © 2011-2022 走看看