LCCUP‘22 力扣杯 二叉树灯饰

题目描述:(链接:力扣)

「力扣嘉年华」的中心广场放置了一个巨型的二叉树形状的装饰树。每个节点上均有一盏灯和三个开关。节点值为 0 表示灯处于「关闭」状态,节点值为 1 表示灯处于「开启」状态。每个节点上的三个开关各自功能如下:

开关 1:切换当前节点的灯的状态;
开关 2:切换 以当前节点为根 的子树中,所有节点上的灯的状态;
开关 3:切换 当前节点及其左右子节点(若存在的话) 上的灯的状态;

给定该装饰的初始状态 root,请返回最少需要操作多少次开关,可以关闭所有节点的灯。

题目示例:

示例1:

输入:root = [1,1,0,null,null,null,1]

输出:2

示例2:

输入:root = [1,1,1,1,null,null,1]

输出:1

示例3:

输入:root = [0,null,0]

输出:0

题目提示:

  • 1 <= 节点个数 <= 10^5
  • 0 <= Node.val <= 1

题目分析:

树状dp,枚举所用的状态转移,一共四种状态,分别是1、根结点不亮,子树全部不亮;2、根结点亮,子树全部不亮;3、根结点亮,子树全部亮;4、根结点不亮,子树全部亮

/**
 * 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:
    // 一共四种转移状态
    tuple<int,int,int,int> dfs(TreeNode* cur){
        if(cur==NULL) return {0,0,0,0};
        auto [la,lb,lc,ld]=dfs(cur->left);
        auto [ra,rb,rc,rd]=dfs(cur->right);
        int v=cur->val;
        // 1、根结点不亮,子树全部不亮
         int x = min({la + ra + (v ? 1 : 0), lb + rb + (v ? 1 : 2), lc + rc + (v ? 1 : 2), ld + rd + (v ? 3 : 2)});
        // 2、根结点亮,子树全部不亮
        int y = min({la + ra + (v ? 0 : 1), lb + rb + (v ? 2 : 1), lc + rc + (v ? 2 : 1), ld + rd + (v ? 2 : 3)});
        // 3、根结点亮,子树全部亮
        int z = min({la + ra + (v ? 2 : 1), lb + rb + (v ? 2 : 3), lc + rc + (v ? 0 : 1), ld + rd + (v ? 2 : 1)});
        // 4、根结点不亮,子树全部亮
        int k = min({la + ra + (v ? 1 : 2), lb + rb + (v ? 3 : 2), lc + rc + (v ? 1 : 0), ld + rd + (v ? 1 : 2)});
        return {x,y,z,k};
    }

    int closeLampInTree(TreeNode* root) {
        auto [x,y,z,k]=dfs(root);
        return min({x,y+1,z+1,k+2});
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值