LeetCode Weekly Contest No. 299 (4/4)

Problem 4. 2322. Minimum Score After Removals on a Tree

题目描述:

There is an undirected connected tree with n nodes labeled from 0 to n - 1 and n - 1 edges.

You are given a 0-indexed integer array nums of length n where nums[i] represents the value of the ith node. You are also given a 2D integer array edges of length n - 1 where edges[i] = [ai, bi] indicates that there is an edge between nodes ai and bi in the tree.

Remove two distinct edges of the tree to form three connected components. For a pair of removed edges, the following steps are defined:

  1. Get the XOR of all the values of the nodes for each of the three components respectively.
  2. The difference between the largest XOR value and the smallest XOR value is the score of the pair.
  • For example, say the three components have the node values: [4,5,7][1,9], and [3,3,3]. The three XOR values are 4 ^ 5 ^ 7 = 61 ^ 9 = 8, and 3 ^ 3 ^ 3 = 3. The largest XOR value is 8 and the smallest XOR value is 3. The score is then 8 - 3 = 5.

Return the minimum score of any possible pair of edge removals on the given tree.

Example 1:

Input: nums = [1,5,5,4,11], edges = [[0,1],[1,2],[1,3],[3,4]]
Output: 9
Explanation: The diagram above shows a way to make a pair of removals.
- The 1st component has nodes [1,3,4] with values [5,4,11]. Its XOR value is 5 ^ 4 ^ 11 = 10.
- The 2nd component has node [0] with value [1]. Its XOR value is 1 = 1.
- The 3rd component has node [2] with value [5]. Its XOR value is 5 = 5.
The score is the difference between the largest and smallest XOR value which is 10 - 1 = 9.
It can be shown that no other pair of removals will obtain a smaller score than 9.

Example 2:

Input: nums = [5,5,2,4,4,2], edges = [[0,1],[1,2],[5,2],[4,3],[1,3]]
Output: 0
Explanation: The diagram above shows a way to make a pair of removals.
- The 1st component has nodes [3,4] with values [4,4]. Its XOR value is 4 ^ 4 = 0.
- The 2nd component has nodes [1,0] with values [5,5]. Its XOR value is 5 ^ 5 = 0.
- The 3rd component has nodes [2,5] with values [2,2]. Its XOR value is 2 ^ 2 = 0.
The score is the difference between the largest and smallest XOR value which is 0 - 0 = 0.
We cannot obtain a smaller score than 0.

Constraints:

  • n == nums.length
  • 3 <= n <= 1000
  • 1 <= nums[i] <= 10^8
  • edges.length == n - 1
  • edges[i].length == 2
  • 0 <= ai, bi < n
  • ai != bi
  • edges represents a valid tree.

解题思路:

这个题没有给出根节点,基本上可以确定用图来表示边,外加一个深度信息(节点的层数,叶子节点为1)。

然后遍历节点,存储每个节点的异或和,异或和递归定义为每个节点与所有子树节点的异或,叶子节点的异或和为自己的值。

然后二重遍历所有的边,计算去除每对儿边后的三组的异或值的最大值,再从所有值中选一个最小值。

代码编写起来比较冗长:

class Solution:
    def minimumScore(self, nums: List[int], edges: List[List[int]]) -> int:
        n, m = len(nums), len(edges)
        G = collections.defaultdict(list)
        degree = collections.defaultdict(int)
        xor_vals = nums[:]
        for e1, e2 in edges:
            G[e1].append(e2)
            G[e2].append(e1)
            degree[e1] += 1
            degree[e2] += 1
        xor = 0
        pq = collections.deque()
        seen = set()
        for i, num in enumerate(nums):
            xor ^= num
            if degree[i] == 1:
                pq.append(i)
                seen.add(i)
        res_children = collections.defaultdict(set)
        while pq:
            cur = pq.popleft()
            for neigh in G[cur]:
                if neigh not in seen:
                    res_children[neigh].add(cur)
                    res_children[neigh] |= res_children[cur]
                    xor_vals[neigh] ^= xor_vals[cur]
                degree[neigh] -= 1
                if degree[neigh] == 1 and len(seen) != n - 1:
                    pq.append(neigh)
                    seen.add(neigh)
        ret = 1e10
        for i in range(m - 1):
            for j in range(i + 1, m):
                p1, q1 = edges[i]
                p2, q2 = edges[j]

                if q1 in res_children[p1]: p1, q1 = q1, p1
                if q2 in res_children[p2]: p2, q2 = q2, p2

                if p2 in res_children[p1]:
                    group = [xor_vals[p2], xor_vals[p1] ^ xor_vals[p2], xor ^ xor_vals[p1]]
                elif p1 in res_children[p2]:
                    group = [xor_vals[p1], xor_vals[p2] ^ xor_vals[p1], xor ^ xor_vals[p2]]
                else:
                    group = [xor_vals[p1], xor_vals[p2], xor ^ xor_vals[p1] ^ xor_vals[p2]]
                ret = min(ret, max(group) - min(group))
        return ret

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值