【LeetCode - 156】上下翻转二叉树

1、题目描述

在这里插入图片描述

2、解题思路

  光看题目还是懵懵懂懂,不如我把一个二叉树倒着过来看:
在这里插入图片描述

  我们可以看出一个规律:对于任意一个节点,它的右结点变为左子节点的左子节点,它自己变为它左子节点的右子结点。

  我们知道,对于一个节点来说,关心的是它的左右子结点,至于它的父节点是谁可以递归求解。

  因此,我们需要对每一个节点的左子节点进行重新设置左右节点。

  定义 DFS 函数,输入一个子树的根节点,返回的是该子树已经上下翻转后的新二叉树的根节点。

  因此,DFS 函数的流程如下:

  1、确定翻转后的新二叉树的根节点 head。如果,node 为叶子节点且 head 为空,则 node 成为新的头结点,head = node;

  2、node 为 null,return;

  3、node 不是叶子节点也不为 null,则先递归把 node 的左右子树翻转好,得到新的左右子节点,然后把新右子节点变为 node 新左子节点的左子节点,node 自己变为新左子节点的右子节点,最后 node 的左右子结点置空,即不再是原来左右子结点的父节点了。

3、解题代码

// Java实现
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    // 处理之后的根节点
     TreeNode head;

    public  TreeNode upsideDownBinaryTree(TreeNode root) {
        if (root == null) {
            return null;
        }
        dfs(root);  // 对 root 进行上下翻转
        return head;
    }

    public  TreeNode dfs(TreeNode node) {
        if (node == null) {
            return null;
        }
        if (node.left == null && node.right == null) {
            if (head == null) {
                // 最左边的节点即为实际的根节点
                head = node;
            }
            return node;
        }
        TreeNode left = dfs(node.left);
        TreeNode right = dfs(node.right);
        if (left != null) {
            // 左孩子的左子树为当前的右节点
            left.left = right;
            // 左孩子的右子树为当前父节点
            left.right = node;
        }
        // 清空的当前父节点的左右子树
        node.right = null;
        node.left = null;
        return node;
    }
}
// c实现
/**
 * Definition for a binary tree node.
  */
struct TreeNode {
	int val;
    struct TreeNode *left;
    struct TreeNode *right;
};

struct TreeNode *newHead = NULL;

struct TreeNode *dfs(struct TreeNode *node)
{
	if(node == NULL) return NULL;

	// 1.叶子节点的处理
	if(node -> left == NULL && node -> right == NULL) 
	{
		if(newHead == NULL)
		{
			newHead = node;
		}
		return node;
	}

	// 2.非叶子节点的处理
	// 2.1 先把左右子树进行上下翻转(如果存在的话)
	struct TreeNode *newLeft = dfs(node -> left);
	struct TreeNode *newRight = dfs(node -> right);
	
	if(newLeft != NULL)
	{
		// 2.2 node 的新右子结点变为新左子节点的左子节点
		newLeft -> left = newRight; 
		// 2.3 node 成为新左子节点的右子节点
		newLeft -> right = node;
	}
	node -> left = NULL;
	node -> right = NULL;
	return node;
}

struct TreeNode *upsideDownBinaryTree(struct TreeNode *root)
{
	if(root == NULL) return NULL;
	dfs(root);
	/** LeetCode的测试用例是使用一个main函数
	*   因此,每次调用upsideDownBinaryTree函数在返回之前应该把全局变量newHead置空
	*   否则,upsideDownBinaryTree会成为一次性函数,因为newHead只有第一次调用的时候不为空
	**/
	struct TreeNode *ans = newHead;
	newHead = NULL;
	return ans;
}
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值