leetcode1145.二叉树着色游戏

题目

有两位极客玩家参与了一场「二叉树着色」的游戏。游戏中,给出二叉树的根节点 root,树上总共有 n 个节点,且 n 为奇数,其中每个节点上的值从 1 到 n 各不相同。

游戏从「一号」玩家开始(「一号」玩家为红色,「二号」玩家为蓝色),最开始时,

「一号」玩家从 [1, n] 中取一个值 x(1 <= x <= n);

「二号」玩家也从 [1, n] 中取一个值 y(1 <= y <= n)且 y != x。

「一号」玩家给值为 x 的节点染上红色,而「二号」玩家给值为 y 的节点染上蓝色。

之后两位玩家轮流进行操作,每一回合,玩家选择一个他之前涂好颜色的节点,将所选节点一个 未着色 的邻节点(即左右子节点、或父节点)进行染色。

如果当前玩家无法找到这样的节点来染色时,他的回合就会被跳过。

若两个玩家都没有可以染色的节点时,游戏结束。着色节点最多的那位玩家获得胜利 ✌️。

现在,假设你是「二号」玩家,根据所给出的输入,假如存在一个 y 值可以确保你赢得这场游戏,则返回 true;若无法获胜,就请返回 false。

示例

在这里插入图片描述
输入:root = [1,2,3,4,5,6,7,8,9,10,11], n = 11, x = 3
输出:True
解释:第二个玩家可以选择值为 2 的节点。

提示

二叉树的根节点为 root,树上由 n 个节点,节点上的值从 1 到 n 各不相同。
n 为奇数。
1 <= x <= n <= 100

思路

结点x将二叉树分为两个或者三个部分,当x结点为根节点时分成两部分,为其他结点时分成三部分。x为根节点,分别计算两部分结点个数,比较是否想等,如果不相等,那么当y结点为与x相邻的结点且y在结点数多的那部分就可以保证胜利;x不是根节点,分别计算三部分的结点个数,取结点数最多的部分,如果结点数大于其他两部分结点数之和(即一号玩家着色结点总数-1),那么只要y为x的相邻节点且在结点数最多部分,就能保证取得胜利。

代码

#class TreeNode:
#    def __init__(self, x):
#       self.val = x
#       self.left = None
#       self.right = None

import math
class Solution:
    def btreeGameWinningMove(self, root, n, x):
        """
        :param root:TreeNode
        :param n: int
        :param x: int
        :return: bool
        """
        if x == root.val:
            if math.log2(n+1) % 1 == 0:
                return False
            else:
                return True
            
        node = TreeNode(0)
        def findnode(root,x,node):
            if not root:
                return
            if root.left:
                if root.left.val == x:
                    node = root.left
                else:
                    node = findnode(root.left,x,node)
            if root.right:
                if root.right.val == x:
                    node = root.right
                else:
                    node = findnode(root.right,x,node)
            return node
        
        node = findnode(root,x,node)


        def nodenum(node):
            cnt = 0
            if not node:
                return cnt
            if node.left:
                cnt += 1
                cnt += nodenum(node.left)
            if node.right:
                cnt += 1
                cnt += nodenum(node.right)
            return cnt
        
        if not node.left:
            leftcnt = 0
        else:
            leftcnt = nodenum(node.left) + 1
        if not node.right:
            rightcnt = 0
        else:
            rightcnt = nodenum(node.right) + 1
        restcnt = n - leftcnt - rightcnt - 1
        print(node.val,node.left,node.right)
        print(leftcnt,rightcnt,restcnt)
        maxcnt = max(leftcnt,rightcnt,restcnt)
        if maxcnt > n - maxcnt:
            return True
        else:
            return False

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值