(58)114. 二叉树展开为链表

题目链接:
https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list/
难度:中等
114. 二叉树展开为链表
给定一个二叉树,原地将它展开为一个单链表。

例如,给定二叉树
	    1
	   / \
	  2   5
	 / \   \
	3   4   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) {
    	// 用来保存前序遍历过程中的node 
        auto vec=vector<TreeNode*>();
        // 栈 回溯
        auto sta=stack<TreeNode*>();
        TreeNode *node=root;
        while(!sta.empty()||node!=nullptr){
        	// 向左遍历
            while(node!=nullptr){
                vec.push_back(node);
                sta.push(node);
                node=node->left;
            }
            // 向左到头 回溯到上一个的node的右子树
            node=sta.top();
            sta.pop();
            node=node->right;
        }
        // 最后一个node必为叶子节点所以本来就是nullptr
        for(int i=1;i<vec.size();++i){
            auto pre=vec.at(i-1);
            auto cur=vec.at(i);
            pre->left=nullptr;
            pre->right=cur;
        }
    }
};

还可以继续优化 题解很强啊。。。
不需要vec记录访问顺序 直接转化为链表

class Solution {
public:
    void flatten(TreeNode* root) {
        if(root==nullptr){
            return;
        }
        auto sta=stack<TreeNode*>();
        sta.push(root);
        // pre记录前一个
        TreeNode *pre=nullptr;
        while(!sta.empty()){
            auto cur=sta.top();
            sta.pop();
            if(pre!=nullptr){
                pre->left=nullptr;
                pre->right=cur;
            }
            auto left=cur->left;
            auto right=cur->right;
            // right先进栈
            if(right!=nullptr){
                sta.push(right);
            }
            if(left!=nullptr){
                sta.push(left);
            }
            pre=cur;
        }
    }
};

还有一种方法 嗯。。。 这种方法我是想不到的 官方牛皮 方向是寻找前驱结点

具体的操作: 对于所有结点枚举{
	对于当前节点cur
		若左子节点不为空:
			则在其左子树中找到最右边的节点,作为前驱节点,将当前节点的右子节点赋给前驱节点的右子节点
			然后将当前节点的左子节点赋给当前节点的右子节点,并将当前节点的左子节点设为空
		若左子节点为空:cur=cur->right

}
我终究还是太菜了。。

class Solution {
public:
    void flatten(TreeNode* root) {
        TreeNode *cur=root;
        while(cur!=nullptr){
            if(cur->left!=nullptr){
                auto node=cur->left;
                auto t=node;
                while(node->right!=nullptr){
                    node=node->right;
                }
                node->right=cur->right;
                cur->right=t;
                cur->left=nullptr;
            }
            cur=cur->right;
        }
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值