算法挑战16: 二叉树展开为链表

6 阅读1分钟

给你二叉树的根结点 root ,请你将它展开为一个单链表:

  • 展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null 。
  • 展开后的单链表应该与二叉树 先序遍历 顺序相同。

思路: 他说是链表,其实还是二叉树, 不过不用左树,只用右树

先用一个数组来存储所有先序遍历出来的节点

再遍历这个数组, 每个node节点为arr[i].left => null; arr[i].right => arr[i+1];

最后返回根节点root就可以

var flatten = function(root) {
    let arr= [];//数组

   function traverse(node){
    if(!node)return;

    //前序遍历
    arr.push(node);

    traverse(node.left);
    traverse(node.right);

   }
   traverse(root);
   //遍历arr
   for(let i = 0; i < arr.length - 1; i++){
        arr[i].left = null;
        arr[i].right = arr[i+1];
   }
   return root;
};

方法二:

    1
   / \
  2   5
 / \   \
3   4   6

//将 1 的左子树插入到右子树的地方
    1
     \
      2         5
     / \         \
    3   4         6  
//将原来的右子树接到左子树的最右边节点
    1
     \
      2          
     / \          
    3   4  
         \
          5
           \
            6

 //将 2 的左子树插入到右子树的地方
    1
     \
      2          
       \          
        3       4  
                 \
                  5
                   \
                    6   
 //将原来的右子树接到左子树的最右边节点
    1
     \
      2          
       \          
        3      
         \
          4  
           \
            5
             \
              6         
  
  ......

作者:windliang
链接:https://leetcode.cn/problems/flatten-binary-tree-to-linked-list/solutions/17274/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by--26/

var flatten = function (root) {
    while (root) {
        //左子树为null,直接考虑下一个节点
        if (!root.left) {
            root = root.right;
        } else {
            //不为空,找左子树最右边的节点
            let pre = root.left;
            while (pre.right) {
                pre = pre.right;
            }
            //把右子树拼接到左子树最右边的节点
            pre.right = root.right;
            //把左子树拼接到当前根节点上
            root.right = root.left;
            root.left = null; //左子树置为null
            //考虑下一个节点
            root = root.right;
        }
    }
};