LeetCode426 将二叉搜索树转化为排序的双向链表

Question:

Convert a binary search tree to doubly linked list with in-order traversal.

Example:

Given a binary search tree:

4

/
2 5
/
1 3
return 1<->2<->3<->4<->5
这道题有很多种问法:

  1. 由BST构造一个新的无环双向链表。

  2. 由BST构造一个新的有环双向链表。

  3. 将BST改造成一个双向链表。

问题1:中序遍历BST,每访问一个新的tree node,构造一个新的list node。将新的list node的prev指针指向之前访问的list node,然后将之前访问的list node的next指针指向新的list node。因为要记录之前访问的list node的信息,我们创建一个state对象,state.prev记录之前访问的list node,state.head记录链表的头节点。如何判断头节点很简单,如果state.prev等于null,说明当前节点之前没有节点了,那么该节点就是头节点。helper函数的定义:以root为根节点的BST构造一个双向链表,并将新链表链接到state.prev节点上去,同时记录头节点和最后访问的节点的信息。

问题2:在问题1的基础上,每往链表中添加一个新节点,将头节点的prev指针指向该新节点,然后新节点的next指针指向头节点。当链表构造完,整个链表自然就是一个循环链表。

问题3:和之前的问题几乎一模一样,因为tree node有两个指针(left,right),list node同样有两个指针(prev,next)。遍历BST的时候,每访问一个tree node,将它的left指针指向之前访问的tree node,将之前访问的tree node的right指针指向当前节点。注意:不可以修改当前访问的tree node的right指针,因为我们需要通过right指针找到下一个访问的tree node。

扫描二维码关注公众号,回复: 4760203 查看本文章

non-cycle:

/**
 * Definition of TreeNode:
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left, right;
 *     public TreeNode(int val) {
 *         this.val = val;
 *         this.left = this.right = null;
 *     }
 * }
 * Definition for Doubly-ListNode.
 * public class DoublyListNode {
 *     int val;
 *     DoublyListNode next, prev;
 *     DoublyListNode(int val) {
 *         this.val = val;
 *         this.next = this.prev = null;
 *     }
 * }
 */

//用来记录list的状态,prev是之前访问的node,head是第一个node
class State {
    DoublyListNode prev;
    DoublyListNode head;
    
    State(DoublyListNode prev, DoublyListNode head) {
        this.prev = prev;
        this.head = head;
    }
    
    State() {
        this.prev = null;
        this.head = null;
    }
}

// 每次新建一个节点,将它指向前一个节点,前一个节点指向它
public class Solution {
    /**
     * @param root: The root of tree
     * @return: the head of doubly list node
     */
    public DoublyListNode bstToDoublyList(TreeNode root) {  
        if(root == null) {
            return null;
        }
        
        // DoublyListNode prev = null, head = null;
        State state = new State();
        helper(root, state);
        
        return state.head;
    }
    
    //helper函数的定义是:将root为根的树变成doubly-linked list然后与state.prev相连接
    private void helper(TreeNode root, State state) {
        if(root == null) {
            return;
        }
        
        helper(root.left, state);
        
        DoublyListNode node = new DoublyListNode(root.val);
        node.prev = state.prev;
        if(state.prev != null) {
            state.prev.next = node;
        }else {
            state.head = node;
        }
        
        state.prev = node;
        helper(root.right, state);
    }
}

cycle:

/**
 * Definition of TreeNode:
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left, right;
 *     public TreeNode(int val) {
 *         this.val = val;
 *         this.left = this.right = null;
 *     }
 * }
 * Definition for Doubly-ListNode.
 * public class DoublyListNode {
 *     int val;
 *     DoublyListNode next, prev;
 *     DoublyListNode(int val) {
 *         this.val = val;
 *         this.next = this.prev = null;
 *     }
 * }
 */

//用来记录list的状态,prev是之前访问的node,head是第一个node
class State {
    DoublyListNode prev;
    DoublyListNode head;
    
    State(DoublyListNode prev, DoublyListNode head) {
        this.prev = prev;
        this.head = head;
    }
    
    State() {
        this.prev = null;
        this.head = null;
    }
}

// 每次新建一个节点,将它指向前一个节点,前一个节点指向它
public class Solution {
    /**
     * @param root: The root of tree
     * @return: the head of doubly list node
     */
    public DoublyListNode bstToDoublyList(TreeNode root) {  
        if(root == null) {
            return null;
        }
        
        // DoublyListNode prev = null, head = null;
        State state = new State();
        helper(root, state);
        
        return state.head;
    }
    
    private void helper(TreeNode root, State state) {
        if(root == null) {
            return;
        }
        
        helper(root.left, state);
        
        DoublyListNode node = new DoublyListNode(root.val);
        node.prev = state.prev;
        if(state.prev != null) {
            state.prev.next = node;
        }else {
            state.head = node;
        }
        
        state.head.prev = node;
        node.next = state.head;
        state.prev = node;
        helper(root.right, state);
    }
}

时间复杂度为O(n),n为树中节点的个数。

猜你喜欢

转载自blog.csdn.net/fruit513/article/details/85681415