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:
- Get the XOR of all the values of the nodes for each of the three components respectively.
- 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 are4 ^ 5 ^ 7 = 6
,1 ^ 9 = 8
, and3 ^ 3 ^ 3 = 3
. The largest XOR value is8
and the smallest XOR value is3
. The score is then8 - 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