题目
有两位极客玩家参与了一场「二叉树着色」的游戏。游戏中,给出二叉树的根节点 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