class Solution {
public:
vector<int> getCoprimes(vector<int>& nums, vector<vector<int>>& edges) {
}
};
1766. 互质树
给你一个 n
个节点的树(也就是一个无环连通无向图),节点编号从 0
到 n - 1
,且恰好有 n - 1
条边,每个节点有一个值。树的 根节点 为 0 号点。
给你一个整数数组 nums
和一个二维数组 edges
来表示这棵树。nums[i]
表示第 i
个点的值,edges[j] = [uj, vj]
表示节点 uj
和节点 vj
在树中有一条边。
当 gcd(x, y) == 1
,我们称两个数 x
和 y
是 互质的 ,其中 gcd(x, y)
是 x
和 y
的 最大公约数 。
从节点 i
到 根 最短路径上的点都是节点 i
的祖先节点。一个节点 不是 它自己的祖先节点。
请你返回一个大小为 n
的数组 ans
,其中 ans[i]
是离节点 i
最近的祖先节点且满足 nums[i]
和 nums[ans[i]]
是 互质的 ,如果不存在这样的祖先节点,ans[i]
为 -1
。
示例 1:
输入:nums = [2,3,3,2], edges = [[0,1],[1,2],[1,3]] 输出:[-1,0,0,1] 解释:上图中,每个节点的值在括号中表示。 - 节点 0 没有互质祖先。 - 节点 1 只有一个祖先节点 0 。它们的值是互质的(gcd(2,3) == 1)。 - 节点 2 有两个祖先节点,分别是节点 1 和节点 0 。节点 1 的值与它的值不是互质的(gcd(3,3) == 3)但节点 0 的值是互质的(gcd(2,3) == 1),所以节点 0 是最近的符合要求的祖先节点。 - 节点 3 有两个祖先节点,分别是节点 1 和节点 0 。它与节点 1 互质(gcd(3,2) == 1),所以节点 1 是离它最近的符合要求的祖先节点。
示例 2:
输入:nums = [5,6,10,2,3,6,15], edges = [[0,1],[0,2],[1,3],[1,4],[2,5],[2,6]] 输出:[-1,0,-1,0,0,0,-1]
提示:
nums.length == n
1 <= nums[i] <= 50
1 <= n <= 105
edges.length == n - 1
edges[j].length == 2
0 <= uj, vj < n
uj != vj
原站题解
golang 解法, 执行用时: 476 ms, 内存消耗: 59.7 MB, 提交时间: 2023-10-25 23:26:22
var prime = make([][]bool, 0) func getCoprimes(nums []int, edges [][]int) []int { var edge = make([][]int, len(nums)) for i := range edge { edge[i] = make([]int, 0) } for _, e := range edges { a, b := e[0], e[1] edge[a] = append(edge[a], b) edge[b] = append(edge[b], a) } if len(prime) == 0 { for i := 0; i < 51; i++ { prime = append(prime, make([]bool, 51)) } for i := 0; i < 51; i++ { for j := i; j < 51; j++ { prime[j][i] = greatestCommonDivisor(i, j) == 1 prime[i][j] = prime[j][i] } } } var set = make(map[int]bool, 0) for _, n := range nums { set[n] = true } var visited = make(map[int]bool, 0) var currents = make([][][]int, 51) for i := 0; i < 51; i++ { currents[i] = make([][]int, 0) } var results = make([]int, len(nums)) var dfs func(node, depth int) dfs = func(node, depth int) { if visited[node] { return } visited[node] = true var value = nums[node] var ans = []int{-1, -1} for i := range set { if len(currents[i]) > 0 && prime[value][i] { var get = currents[i][len(currents[i])-1] if get[1] > ans[1] { ans = get } } } results[node] = ans[0] for _, child := range edge[node] { currents[value] = append(currents[value], []int{node, depth}) dfs(child, depth+1) currents[value] = currents[value][0 : len(currents[value])-1] } } dfs(0, 0) return results } func greatestCommonDivisor(a int, b int) int { for b != 0 { return greatestCommonDivisor(b, a%b) } return a }
python3 解法, 执行用时: 2084 ms, 内存消耗: 117.9 MB, 提交时间: 2023-10-25 23:25:54
class Solution: def getCoprimes(self, nums: List[int], edges: List[List[int]]) -> List[int]: graph = collections.defaultdict(list) for edge in edges: i, j = edge graph[i].append(j) graph[j].append(i) stacks = [[] for _ in range(51)] res = [-1 for i in range(len(nums))] def dfs(node, parent, depth): candidates = [] for i in range(1, len(stacks)): if len(stacks[i]) > 0 and math.gcd(i, nums[node]) == 1: candidates.append(stacks[i][-1]) maxDepth = -1 resNode = -1 for candidate in candidates: d, n = candidate if d > maxDepth: maxDepth = d resNode = n res[node] = resNode stacks[nums[node]].append((depth, node)) children = graph[node] for child in children: if child != parent: dfs(child, node, depth + 1) stacks[nums[node]].pop() dfs(0, None, 0) return res
cpp 解法, 执行用时: 556 ms, 内存消耗: 172.6 MB, 提交时间: 2023-10-25 23:24:58
class Solution { public: vector<vector<int>> G; stack<pair<int,int>> lasts[55]; vector<int> res; void dfs(int node, int pre, int level, vector<int>& a) { int re = -1, lev = -1; for(int i = 1; i <= 50; ++i) { if(lasts[i].size() && lasts[i].top().first > lev && __gcd(i, a[node]) == 1) { re = lasts[i].top().second; lev = lasts[i].top().first; } } res[node] = re; for(int ne : G[node]) { if(ne != pre) { lasts[a[node]].push({level, node}); dfs(ne, node, level + 1, a); lasts[a[node]].pop(); } } } vector<int> getCoprimes(vector<int>& nums, vector<vector<int>>& edges) { int n = nums.size(); G.resize(n); for(auto& e : edges) { G[e[0]].push_back(e[1]); G[e[1]].push_back(e[0]); } res.resize(n); dfs(0, -1, 0, nums); return res; } };