Leetcode 226 Invert Binary Tree 反转二叉树

原题地址

https://leetcode.com/problems/invert-binary-tree/

题目描述

Invert a binary tree.
反转一棵二叉树。

from

     4
   /   \
  2     7
 / \   / \
1   3 6   9

to

     4
   /   \
  7     2
 / \   / \
9   6 3   1

Trivia:
轶事:

This problem was inspired by this original tweet by Max Howell:
这个问题的灵感来自Max Howell的原始推文(tweet)

Google: 90% of our engineers use the software you wrote (Homebrew), but you can’t invert a binary tree on a whiteboard so fuck off.
90%的Google员工都在用你写的软件(Homebrew),然而你无法在一个白板上写出反转二叉树的算法,所以我们不要你。

关于这个事件,知乎上还有一个讨论 如何评价 Homebrew 作者因为不会在白板上翻转二叉树而被谷歌面试拒绝?

此处不作过多讨论,看一下这个题就好。

解题思路

直观上来看,题目要求很清楚,就是左右对调。那么如何实现呢?可以考虑将每一层的结点从右侧开始往左依次添加到一个队列中,然后把队列中的结点依次链接到上一层的结点上去(假设上一层已经完成了反转)

要想实现上述思路,我们假设第i-1层已经反转结束了,正要对第i层执行反转操作,我们从最右侧的结点开始,依次将每个结点node放入队列queueLast中,并且把每个结点的右孩子和左孩子放入队列queueCur中(先放右孩子再放左孩子)。这样处理结束后,queueLast中存储的就是第i层结点反转之后的从左至右的顺序,然后把queueCur中的结点依次链接到queueLast的结点上去即可完成第i层的反转。

代码

class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        if (root == NULL) return NULL;
        queue<TreeNode*> last, lastTmp, cur, curTmp;
        last.push(root);
        cur.push(root->right);
        cur.push(root->left);

        TreeNode* nodeTop, * nodeBottom;
        while (!last.empty()) {
            while (!last.empty()) { // 把下一层结点链接到上一层结点上去
                                    // 并反转下一层的结点
                nodeTop = last.front();
                last.pop();
                nodeBottom = cur.front();
                cur.pop();
                nodeTop->left = nodeBottom; // 把结点链接到上一层结点上去
                if (nodeBottom) {   // 把当前层的结点反转,放入队列,以备下层循环使用
                    lastTmp.push(nodeBottom);
                    curTmp.push(nodeBottom->right);
                    curTmp.push(nodeBottom->left);
                }
                nodeBottom = cur.front();
                cur.pop();
                nodeTop->right = nodeBottom; // 把结点链接到上一层结点上去
                if (nodeBottom) {   // 把当前层的结点反转,放入队列,以备下层循环使用
                    lastTmp.push(nodeBottom);
                    curTmp.push(nodeBottom->right);
                    curTmp.push(nodeBottom->left);
                }
            }
            while (!lastTmp.empty()) {
                last.push(lastTmp.front());
                lastTmp.pop();
            }
            while (!curTmp.empty()) {
                cur.push(curTmp.front());
                curTmp.pop();
            }
        }
        return root;
    }
};

完整代码 https://github.com/Orange1991/leetcode/blob/master/226/cpp/main.cpp

除此之外,还有用vector实现的一个版本,有兴趣可参考https://github.com/Orange1991/leetcode/blob/master/226/cpp/s2.cpp

测试数据

before invert : 4 7 2 1 3 6 9 5 4 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 
after invert : 4 2 7 9 6 3 1 NULL NULL NULL NULL NULL NULL 4 5 NULL NULL NULL NULL 
before invert : 1 2 3 4 NULL NULL 5 NULL NULL NULL NULL 
after invert : 1 3 2 5 NULL NULL 4 NULL NULL NULL NULL 

2015/8/28

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值