• 剑指 Offer 36. 二叉搜索树与双向链表


    剑指 Offer 36. 二叉搜索树与双向链表

    Difficulty: 中等

    输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。

    为了让您更好地理解问题,以下面的二叉搜索树为例:

    我们希望将这个二叉搜索树转化为双向循环链表。链表中的每个节点都有一个前驱和后继指针。对于双向循环链表,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点。

    下图展示了上面的二叉搜索树转化成的链表。“head” 表示指向链表中有最小元素的节点。

    特别地,我们希望可以就地完成转换操作。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继。还需要返回链表中的第一个节点的指针。

    注意:本题与主站 426 题相同:

    注意:此题对比原题有改动。

    Solution

    思路:采用后序遍历,先获取左子树返回的双向链表,再获取右子树的双向链表。那么根结点就是两个链表的连接点。需要考虑的情况有两个:

    • 有左子树,也有右子树
    • 左子树或右子树不存在,或者左右子树都不存在

    第一种情况很好直接使用返回的值就好。第二种情况,如果左子树不存在,那么当前结点就是表头;如果右子树不存在,那么当前绩点就是表尾;如果都不存在,那么当前双向链表就只有一个结点。

    Language: java

    ​/*
    // Definition for a Node.
    class Node {
        public int val;
        public Node left;
        public Node right;
    
        public Node() {}
    
        public Node(int _val) {
            val = _val;
        }
    
        public Node(int _val,Node _left,Node _right) {
            val = _val;
            left = _left;
            right = _right;
        }
    };
    */
    class Solution {
        public Node treeToDoublyList(Node root) {
            if(root == null) return null;
            Node[] res = helper(root);
            res[0].left = res[1];
            res[1].right = res[0];
            return res[0];
        }
        /*方法返回Node[2],其中Node[0]表示表头,Node[1]表示表尾*/
        private Node[] helper(Node root){
            if(root == null) return new Node[]{null, null};
            Node[] left = helper(root.left);
            Node[] right = helper(root.right);
            Node head = null, tail = null;
            if(left[0] == null && left[1] == null){  
                head = root;  //当前结点没有左子树时,该结点就是表头
            }else{
                root.left = left[1];
                left[1].right = root;
                head = left[0];
            }
            if(right[0] == null && right[1] == null){
                tail = root;  //当前结点没有右子树时,该结点就是表尾
            }else{
                root.right = right[0];
                right[0].left = root;
                tail = right[1];
            }
            return new Node[]{head, tail};
        }
    }
    
  • 相关阅读:
    oracle归档日志增长过快处理方法
    Oracle“死锁”模拟
    Oracle 手工清除回滚段的几种方法
    Oracle 一次 锁表 处理小记
    Oracle中如何判断一个字符串是否含有汉字
    机房收费系统验收总结
    hdu 4747 Mex (线段树)
    Java 5 的新标准语法和用法详解集锦
    java类加载器行为[笔记]
    poj1330Nearest Common Ancestors(LCA小结)
  • 原文地址:https://www.cnblogs.com/liuyongyu/p/14464444.html
Copyright © 2020-2023  润新知