【leetcode】Flatten Binary Tree to Linked List (middle)

Given a binary tree, flatten it to a linked list in-place.

For example,
Given

         1
        /        2   5
      / \        3   4   6

The flattened tree should look like:

   1
         2
             3
                 4
                     5
                         6

思路:

用先序遍历,得到的是从小到大的顺序。把先序遍历变形一下:

void flatten(TreeNode* root) {
        if(NULL == root) return;
        vector<TreeNode *> v;
        v.push_back(root);
        TreeNode * pCur = NULL;
        TreeNode * p = NULL;

        while(!v.empty())
        {
            pCur = p = v.back();
            while(NULL != p->left)  //向左移动时只要把当前指针移动即可,因为是按照从小大的顺序的
            {
                v.push_back(p->left);
                pCur = p = p->left;
            }

            while(!v.empty() && (p = v.back()->right) == NULL) //找到下一个要处理的元素,一定是一个右子树
                v.pop_back();
            if(!v.empty())
                v.pop_back();

            if(p != NULL)  //把待处理的右子树连在当前已经铺平的数的左子树上
            {
                v.push_back(p);
                pCur->left = p;
            }
        }

        p = root;
        while(p != NULL) //镜像,全部转移到右子树上
        {
            p->right = p->left;
            p->left = NULL;
            p = p->right;
        }
    }

我发现,我太依赖非递归了,其实有的时候用递归更好。比如大神的版本:

private TreeNode prev = null;

public void flatten(TreeNode root) {
    if (root == null)
        return;
    flatten(root.right);
    flatten(root.left);
    root.right = prev;
    root.left = null;
    prev = root;
}

先把右子树放平,再把左子树放平。因为每次都先处理右子树,所以prev是数值从大到小的一个记录,每次prev都是恰比当前根节点大一点的那个指针的位置。(不大好理解)

下面这个,跟上面的思路很像,但是会容易理解很多:

public void flatten(TreeNode root) {
        if (root == null) return;

        TreeNode left = root.left;
        TreeNode right = root.right;

        root.left = null;

        flatten(left);
        flatten(right);

        root.right = left;
        TreeNode cur = root;
        while (cur.right != null) cur = cur.right;
        cur.right = right;
    }

也是先铺平右子树,再铺平左子树。一定是右子树的值大于左子树,所以先把左子树连接到根节点右侧,再把右子树连在后面。 这个代码平铺左右子树的顺序没限制。反过来也行。

上面思路的非递归版本: 也是需要想半天才能看懂的。每次先把紧接着子树连好,其他代码都是从叶节点开始连接,这个是从根节点开始的。

public void flatten(TreeNode root) {
        if (root == null) return;
        Stack<TreeNode> stk = new Stack<TreeNode>();
        stk.push(root);
        while (!stk.isEmpty()){
            TreeNode curr = stk.pop();
            if (curr.right!=null)
                 stk.push(curr.right);
            if (curr.left!=null)
                 stk.push(curr.left);
            if (!stk.isEmpty())
                 curr.right = stk.peek();
            curr.left = null;  // dont forget this!!
        }
    }
时间: 2024-10-16 04:16:58

【leetcode】Flatten Binary Tree to Linked List (middle)的相关文章

【LeetCode】Flatten Binary Tree to Linked List

题目:Flatten Binary Tree to Linked List <span style="font-size:18px;">/**LeetCode Flatten Binary Tree to Linked List * 题意:给定一个二叉树,将其转变为一个相当于单链表的结构,观察可知该结构即:每一个节点左儿子为空,右儿子指向自己先序遍历时的下一个节点 * 思路:有观察可得,应对其进行先序遍历,得到正确的序列连接起来 * Definition for binar

【LeetCode】Flatten Binary Tree to Linked List 解题报告

[题目] Given a binary tree, flatten it to a linked list in-place. For example, Given 1 / 2 5 / \ 3 4 6 The flattened tree should look like: 1 2 3 4 5 6 [解析] 题意是把一棵二叉树按照先序遍历的方式放到一棵只有右支树的二叉树中. 最开始想的思路是递归发,后来发现这样会溢出. 然后就用一个栈和一个队列来实现,队列用来存储先序遍历的结果,栈用于先序遍历.

【树】Flatten Binary Tree to Linked List(先序遍历)

题目: Given a binary tree, flatten it to a linked list in-place. For example,Given 1 / 2 5 / \ 3 4 6 The flattened tree should look like: 1 2 3 4 5 6 思路: 按照树的先序遍历顺序把节点串联起来即可. /** * Definition for a binary tree node. * function TreeNode(val) { * this.va

Leetcode 之Flatten Binary Tree to Linked List(50)

将左子树接到右子树之前,递归解决 void flatten(TreeNode *root) { if (root == nullptr)return; flatten(root->left); flatten(root->right); //如果没有左子树,直接返回即可 if (root->left == nullptr)return; p = root->left; //寻找左子树的最后一个结点 while (p->right)p = p->right; //将右结点

【Leetcode】【Medium】Flatten Binary Tree to Linked List

Given a binary tree, flatten it to a linked list in-place. For example,Given 1 / 2 5 / \ 3 4 6 The flattened tree should look like: 1 2 3 4 5 6 解题思路: 看上去很简单,使用二叉树的中序遍历就可以实现.但是题目的小曲点在于要在原tree上修改,如果将左儿子放在右儿子位置上,会丢失右子树,导致遍历失败. 解决方法有两种: 1.不使用多余空间,将右子树放在左

leetcode 114. Flatten Binary Tree to Linked List (Python版)

题目: Given a binary tree, flatten it to a linked list in-place. 算法思路: 其实该题目就是二叉树前序遍历的变形 我代码沿用leetcode 144. Binary Tree Preorder Traversal 代码: class Solution(object):     def preorderTraversal(self, root):         """         :type root: Tree

【leetcode】Remove Duplicates from Sorted List II (middle)

Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list. For example,Given 1->2->3->3->4->4->5, return 1->2->5.Given 1->1->1->2->3, return 2->3.

【leetcode】Kth Largest Element in an Array (middle)☆

Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element. For example,Given [3,2,1,5,6,4] and k = 2, return 5. 思路: 堆.讲解:二叉堆 class Solution { public: //新插入i结点 其父节点为(i

【leetcode】Search in Rotated Sorted Array II(middle)☆

Follow up for "Search in Rotated Sorted Array":What if duplicates are allowed? Would this affect the run-time complexity? How and why? Write a function to determine if a given target is in the array. 我的思路: 太混乱了 不提了.注意关键区分依据 排好序的一定是从小到大的 看大神的吧: b