1、题目描述
2、解题思路
看到关键词“二叉搜索树”、“排序”可知肯定和递归有关;
首先定义一个 first 表示排列好了之后的链表的第一个结点,last 表示排列好了之后的最后一个结点;
定义一个函数 void helper(Node node) 表示把以 node 为根节点的二叉树进行从小到大排序成为链表,转换后,first 指向这个链表的第一个节点,last 指向这个链表的最后一个节点。
定义一个 helper 函数:
1、如果传进来的 node 为 null,什么也不做;非空则进入下一步;
2、调用 helper 转化 node 的左子树:helper(node.left),转化好了左子树后,此时 first 指向转化好的链表第一个节点,last 指向转化好的链表最后一个节点;
3、last = node 更新 last 为当前节点(二叉搜索树的根节点大于左子树所有节点)
4、调用 helper 转化 node 的右子树:helper(node.left),转化好了右子树,此时的 first 就是以 node 为根节点转化成的链表的第一个节点,last 是最后一个节点;
有了 helper 函数,对于 root 的排列直接调用 helper(root) 即可,此时 first 就是头结点,last 为最末端节点;
题目要求循环链表,则头尾连结即可:last.right = first;first.left = last;
返回 first。
3、解题代码
/*
// 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 {
private Node first;
private Node last;
public Node treeToDoublyList(Node root) {
if (root == null) return root;
helper(root);
last.right = first;
first.left = last;
return first;
}
private void helper(Node node) {
if (node != null) {
// 处理左子节点
helper(node.left); // 左子树已经从小到大排列好了
if (last != null) { // node.left 至少有一个结点
last.right = node;
node.left = last;
}else {
first = node;
}
// 处理右子节点
last = node;
helper(node.right);
}
}
}