题目描述 & 链接
Leetcode 426 : 将BST结构转化成双链表结构,使得每一个节点连接他的前驱结点和后继节点,并且头,尾两个节点也要相连。要求不开额外空间
题目思路
这道题我给点个赞,让我对于中序遍历DFS模板有了更深刻的理解。首先如果可以开额外空间的话怎么做?以为二叉树中序遍历有个隐藏性质:中序遍历中当前节点上一个点即为前驱节点,下一个点即为后继节点。那么可以将BST结构以中序遍历顺序,保存并遍历该数组让每一个点与左右相连即可。
如果不使用额外空间应该如何做。我们先看一下BST中序遍历模板,如下
private void dfs(Node root) {
if(root==null) return;
dfs(root.left);
// 以下就是处理区 - 显示当前节点
System.out.println(root.val);
//
dfs(root.right);
}
我们可以在每一次出递归开始做处理时,把前驱节点与当前节点连接起来,然后在把头部和尾部两个节点连接即可。整体思路,首先需要保存头,尾两个节点,递归中第一次进入"处理区"就是第一个节点,递归中最后一次进入"处理区"就是最后一个节点。在递归中得到前驱节点的办法,定义一个全局变量,每一次处理区处理逻辑完毕后保存当前节点,这样下一次进入处理区时,保存的节点就是该节点的前驱节点。
处理区逻辑,就是将当前节点与前驱节点相连,整体代码如下:
/*
// 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 {
Node first = null;
Node last = null;
public Node treeToDoublyList(Node root) {
if(root==null) return null;
//中序遍历前驱结点上一个后继节点下一个
dfs(root);
first.left = last;
last.right = first;
return first;
}
private void dfs(Node root) {
if(root==null) return;
dfs(root.left);
// do something
// 第一次进入处理区的点一定是第一个点(最左的点)
if(last!=null) {
// 中间某一个点
// 前面一个点就是last
last.right = root;
root.left = last;
}
if(first==null) first = root;
last = root; // last 一直更新直到最后一次进入也就是最右边那个点
dfs(root.right);
}
}
时间复杂度:;空间复杂度:
即递归深度。