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 are 4 ^ 5 ^ 7 = 6, 1 ^ 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] <= 108
edges.length == n - 1
edges[i].length == 2
0 <= ai, bi < n
ai != bi
edges represents a valid tree.
Solutions
Solution 1: DFS + Subtree XOR Sum
Thinking
Deleting two edges yields three components; the score is the range of their XORs. \(n \le 1000\), so pairing edges and recomputing XOR is heavy. The whole-tree XOR \(s\) is fixed, and a component XOR equals a subtree XOR after rooting.
Delete one edge first to get the root-side XOR \(s_1\). DFS inside that block; each subtree XOR \(s_2\) is the second cut. The three values are \(s\oplus s_1\), \(s_2\), and \(s_1\oplus s_2\). Trying every root and neighbor covers all unordered edge pairs.
We denote the XOR sum of the tree as \(s\), i.e., \(s = \textit{nums}[0] \oplus \textit{nums}[1] \oplus \ldots \oplus \textit{nums}[n-1]\).
Next, we enumerate each node \(i\) in \([0..n)\) as the root of the tree, and treat the edge connecting the root node to some child node \(j\) as the first edge to be removed. This gives us two connected components. We denote the XOR sum of the connected component containing root node \(i\) as \(s_1\), then we perform DFS on the connected component containing root node \(i\) to calculate the XOR sum of each subtree, denoting each XOR sum calculated by DFS as \(s_2\). The XOR sums of the three connected components are \(s \oplus s_1\), \(s_2\), and \(s_1 \oplus s_2\). We need to calculate the maximum and minimum values of these three XOR sums, denoted as \(mx\) and \(mn\). For each enumerated case, the score is \(mx - mn\). We find the minimum value among all cases as the answer.
The XOR sum of each subtree can be calculated through DFS. We define a function \(\textit{dfs}(i, fa)\), which represents starting DFS from node \(i\), where \(fa\) is the parent node of node \(i\). The function returns the XOR sum of the subtree rooted at node \(i\).
The time complexity is \(O(n^2)\), and the space complexity is \(O(n)\), where \(n\) is the number of nodes in the tree.
Deleting two edges yields three components, and the score is the range of their XOR sums. With \(n \le 1000\), pairing every two edges and scanning the whole tree for each pair is heavier than necessary. The XOR \(s\) of the whole tree is fixed, and after one edge is removed a component XOR is the subtree XOR under that orientation. Enumerate the first deleted edge to obtain the root-side XOR \(s_1\), then treat each subtree XOR \(s_2\) inside that component as the second cut. The three values are \(s \oplus s_1\), \(s_2\), and \(s_1 \oplus s_2\). Recursing along a chain uses a call depth equal to the node count and overflows Python at \(n = 1000\). The stack therefore stores \((\textit{node}, \textit{parent}, \textit{state})\): state \(0\) pushes the exit marker and then the children, and state \(1\) writes the subtree XOR after the children are ready. The first walk produces \(s_1\), and the second walk updates the range for every subtree \(s_2\).
Denote the XOR sum of the tree by \(s\), that is, \(s = \textit{nums}[0] \oplus \textit{nums}[1] \oplus \ldots \oplus \textit{nums}[n-1]\).
Enumerate each node \(i\) in \([0..n)\) and treat the edge between \(i\) and a neighbor \(j\) as the first deleted edge. This splits the tree into two components. Let \(s_1\) be the XOR sum of the component that contains \(i\), and let \(s_2\) be the XOR sum of a subtree inside that component. The three component XOR sums are \(s \oplus s_1\), \(s_2\), and \(s_1 \oplus s_2\). The score of this deletion is the difference between their maximum and minimum, and the answer is the minimum score over every deletion. Trying every node and every incident edge covers all unordered pairs of edges.
Subtree XOR sums are filled in postorder on an explicit stack. Each frame is \((\textit{node}, \textit{parent}, \textit{state})\). State \(0\) pushes the exit marker and then every neighbor other than the parent. State \(1\) XORs the node value with each finished child subtree. The first walk returns only \(s_1\), the XOR of the component that contains \(i\) and does not cross \(j\). The second walk, after each subtree XOR \(s_2\) is known, updates the answer with the three values above. The order of the children does not change the range.
The time complexity is \(O(n^2)\), and the space complexity is \(O(n)\), where \(n\) is the number of nodes in the tree.