LeetCode 114. Flatten Binary Tree to Linked List

博客围绕LeetCode 114题,即把二叉树按先序遍历“拍扁”成不含左孩子的树形结构。强调要在原结构修改,不能用new TreeNode。提出用栈存右子树,将左孩子移到右侧的算法,模拟操作过程得出此设计思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

114. Flatten Binary Tree to Linked List

题目中要求我们把一个二叉树按先序遍历“拍扁”,看到这题的第一反应肯定是先序遍历同时建个链表返回表头就好了?
有意思的是题目要求的结果是一个不含左孩子的树形结构,返回类型也是void,即提醒你要在原结构里修改,所以凡是含有new TreeNode的解决方案肯定是不合适的,在实际的场景中,去拷贝一个非常大的树的内存消耗也是很大的

Solution:

先来看解法,如果让你而不是计算机来完成这个操作,你会怎么做?

    1
   / \
  2   5
 / \   \
3   4   6

对于上面这个结构,我是这样操作的:
首先不管5,6(揣兜里),把1画在纸上,再不管4(也揣兜里),把2连在1右侧画在纸上,然后把3连在2右侧画在纸上:

纸上:
1           
 \
  2
   \
    3
 
兜里:
 4
 
 5
  \
   6

左边到头了,这时再把兜里的4掏出来接到3后面画纸上;又到头了,只能从兜里掏出5和6;5画在4后面,6揣到兜里;又到头了,再从兜里掏出6…

想必到了这里规律已经能看出来了,左边的画到上一个节点后面,右边的揣兜里,到头了就从兜里掏,掏出来的子树重复以上过程…值得一提的是,我们用的这个兜显然是个后入先出的结构

就这样,用一个内容是<TreeNode*>的栈结构去当兜存右子树,再把左孩子移到右侧的算法设计完成

Talk is cheap:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    void flatten(TreeNode* root) {
        if (!root) return;
        stack<TreeNode*> waitstack;
        TreeNode* cur = root;
        while(cur->right || cur->left || !waitstack.empty()) {
            // cout <<"cur->val"<<cur->val
            // <<"cur->left"<<cur->left
            // <<"cur->right"<<cur->right
            // <<"stack.size()"<<waitstack.size()
            // <<endl;
            while(cur->right && !cur->left) {
                cur = cur->right;
            }
            if(cur->right) {
                waitstack.push(cur->right);
                cur->right = nullptr; 
            }
            if(cur->left) {
                cur->right = cur->left;
                cur->left = nullptr;
                cur = cur->right;
            }else if(!waitstack.empty()) {
                cur->right = waitstack.top();
                waitstack.pop();
                cur = cur->right;
            }
        }
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值