Skip to content

Latest commit

 

History

History
234 lines (184 loc) · 6.86 KB

File metadata and controls

234 lines (184 loc) · 6.86 KB

English Version

题目描述

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

 

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

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

「二号」玩家也从 [1, n] 中取一个值 y1 <= 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 个节点,节点上的值从 1n 各不相同。
  • n 为奇数。
  • 1 <= x <= n <= 100

解法

方法一:DFS

先通过 $DFS$,找到 $x$ 所在的节点,我们记为 $node$。然后统计 $node$ 的左子树、右子树、父节点方向上的节点个数。如果这三个方向上有任何一个节点个数超过了节点总数的一半,则存在一个必胜策略。

这里 $node$ 父节点方向上的节点个数,可以由节点总数 $n$ 减去 $node$ 及其 $node$ 的左右子树节点数之和得到。

时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是节点总数。

Python3

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def btreeGameWinningMove(self, root: Optional[TreeNode], n: int, x: int) -> bool:
        def dfs(root):
            if root is None or root.val == x:
                return root
            return dfs(root.left) or dfs(root.right)

        def count(root):
            if root is None:
                return 0
            return 1 + count(root.left) + count(root.right)

        node = dfs(root)
        l, r = count(node.left), count(node.right)
        t = n - l - r - 1
        m = max(l, r, t)
        return m > n - m

Java

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean btreeGameWinningMove(TreeNode root, int n, int x) {
        TreeNode node = dfs(root, x);
        int l = count(node.left);
        int r = count(node.right);
        int m = Math.max(Math.max(l, r), n - l - r - 1);
        return m > n - m;
    }

    private int count(TreeNode node) {
        if (node == null) {
            return 0;
        }
        return 1 + count(node.left) + count(node.right);
    }

    private TreeNode dfs(TreeNode root, int x) {
        if (root == null || root.val == x) {
            return root;
        }
        TreeNode l = dfs(root.left, x);
        if (l != null) {
            return l;
        }
        return dfs(root.right, x);
    }
}

C++

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    bool btreeGameWinningMove(TreeNode* root, int n, int x) {
        TreeNode* node = dfs(root, x);
        int l = count(node->left);
        int r = count(node->right);
        int m = max(max(l, r), n - l - r - 1);
        return m > n - m;
    }

    int count(TreeNode* root) {
        if (!root) return 0;
        return 1 + count(root->left) + count(root->right);
    }

    TreeNode* dfs(TreeNode* root, int x) {
        if (!root || root->val == x) return root;
        auto l = dfs(root->left, x);
        return l ? l : dfs(root->right, x);
    }
};

Go

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func btreeGameWinningMove(root *TreeNode, n int, x int) bool {
	var dfs func(*TreeNode) *TreeNode
	dfs = func(root *TreeNode) *TreeNode {
		if root == nil || root.Val == x {
			return root
		}
		l := dfs(root.Left)
		if l != nil {
			return l
		}
		return dfs(root.Right)
	}
	var count func(*TreeNode) int
	count = func(root *TreeNode) int {
		if root == nil {
			return 0
		}
		return 1 + count(root.Left) + count(root.Right)
	}
	node := dfs(root)
	l, r := count(node.Left), count(node.Right)
	m := max(max(l, r), n-l-r-1)
	return m > n-m
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

...