LeetCode 114.二叉树展开为列表

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

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

示例 1:

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

示例 2:

输入:root = []
输出:[]
示例 3:

输入:root = [0]
输出:[0]
 

提示:

树中结点数在范围 [0, 2000] 内
-100 <= Node.val <= 100
 

进阶:你可以使用原地算法(O(1) 额外空间)展开这棵树吗?

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/flatten-binary-tree-to-linked-list 

1.dfs呗: 

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
	public:
		queue<TreeNode*>q;
		void dfs(TreeNode* root) {
			if(!root)return;
			q.emplace(root);
			dfs(root->left);
			dfs(root->right);
		}
		void flatten(TreeNode* root) {
			if(root) {
				dfs(root);
				TreeNode* root1=q.front();
				q.pop();
				while(!q.empty()) {
					root1->left=nullptr;
					root1->right=q.front();
					root1=q.front();
					q.pop();
				}
			}
		}
};

2.可以发现展开的顺序其实就是二叉树的先序遍历。算法和 94 题中序遍历的 Morris 算法有些神似,

1.将左子树插入到右子树的地方
2.将原来的右子树接到左子树的最右边节点
3.考虑新的右子树的根节点,一直重复上边的过程,直到新的右子树为 null

    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         
  

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
	public:
		void flatten(TreeNode* root) {
			TreeNode *curr = root;

			while(curr!=nullptr) {
				if(curr->left!=nullptr) {
					auto next=curr->left;
					auto pred=next;
					while(pred->right!=nullptr) {
						pred=pred->right;
					}
					pred->right=curr->right;
					curr->left=nullptr;
					curr->right=next;
				}
				curr=curr->right;
			}
		}
};

空间复杂度O(1)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值