剑指offer_36_复杂链表的复制【javascript】

49 阅读1分钟

题目

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。对于双向循环列表,你可以将左右孩子指针作为双向循环链表的前驱和后继指针,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点。

题目链接

leetcode.cn/problems/er…

示例

输入:root = [4,2,5,1,3] 
输出:[1,2,3,4,5]

示例 2:
输入:root = [2,1,3]
输出:[1,2,3]

示例 3:
输入:root = []
输出:[]
解释:输入是空树,所以输出也是空链表。

示例 4:
输入:root = [1]
输出:[1]

提示:

  • -1000 <= Node.val <= 1000
  • Node.left.val < Node.val < Node.right.val
  • Node.val 的所有值都是独一无二的
  • 0 <= Number of Nodes <= 2000 **注意:**本题与主站 426 题相同:leetcode-cn.com/problems/co…

题解

DFS

复杂度分析:

  • 时间复杂度 O(N) : N 为二叉树的节点数,中序遍历需要访问所有节点。
  • 空间复杂度 O(N) : 最差情况下,即树退化为链表时,递归深度达到 N,系统使用 O(N) 栈空间。
/**
 * // Definition for a Node.
 * function Node(val,left,right) {
 *    this.val = val;
 *    this.left = left;
 *    this.right = right;
 * };
 */

/**
 * @param {Node} root
 * @return {Node}
 */

var treeToDoublyList = function (root) {
	function dfs(root) {
		if (root == null) return null; // 递归边界: 叶子结点返回
		dfs(root.left);
		// 当 pre === null 的时候,为最小的叶子节点,设置成链表头结点
		pre != null ? pre.right = root : head = root
		root.left = pre;
		pre = root; // 链表指针向右移动
		dfs(root.right);
	}

	let pre = null, head = null;
  if (root === null) return root;
  dfs(root);
  head.left = pre;
  pre.right = head;
  return head;
};