1766. Tree of Coprimes

问题:

给定一棵树,root=0

每个节点id有值nums[id]

求每个节点的所有祖先中,最近&&与其值互质的父节点。

Example 1:
Input: nums = [2,3,3,2], edges = [[0,1],[1,2],[1,3]]
Output: [-1,0,0,1]
Explanation: In the above figure, each node's value is in parentheses.
- Node 0 has no coprime ancestors.
- Node 1 has only one ancestor, node 0. Their values are coprime (gcd(2,3) == 1).
- Node 2 has two ancestors, nodes 1 and 0. Node 1's value is not coprime (gcd(3,3) == 3), but node 0's
  value is (gcd(2,3) == 1), so node 0 is the closest valid ancestor.
- Node 3 has two ancestors, nodes 1 and 0. It is coprime with node 1 (gcd(3,2) == 1), so node 1 is its
  closest valid ancestor.


Example 2:
Input: nums = [5,6,10,2,3,6,15], edges = [[0,1],[0,2],[1,3],[1,4],[2,5],[2,6]]
Output: [-1,0,-1,0,0,0,-1]
 

Constraints:
nums.length == n
1 <= nums[i] <= 50
1 <= n <= 105
edges.length == n - 1
edges[j].length == 2
0 <= uj, vj < n
uj != vj

  

example 1:

 

 

example 2:

 

 

解法:DFS

思路

  • 对树进行深度优先遍历DFS,那么每次遍历出来的一条线:即是一条继承线。使用ancestor进行记录。
    • 对于每个当前的节点 i
    • 我们需要找到其祖先ancestor中,与他互质的祖先们,
      • 然后在这些祖先中,找到level最大,即离 i 最近。

 

  • 那么我们先构造互质关系cops
    • 值 i,的互质数有 {值a,值b,值c...}
    • cops[i] = {a,b,c...}
  • 这样一个unordered_map

⚠️ 注意:由于构造是以数值为基础,那么我们为了不重复计算,使用unordered_set,将所有nums过滤出来,再进行构造。

 

  • 对于当前节点 i,值为 nums[i]
  • 找到这个值的所有互质数,cops[nums[i]]
    • 对于其中一个互质数,onecop in cops[nums[i]]
    • 祖先中存在这个数onecop,ancestor[onecop]是所有值为onecop的祖先(可能有多个值相同的祖先)
      • 取最后一个祖先,一定是最后加入ancestor的,也是离 i 最近&&值为onecop的祖先。
  • 同样的,找到所有不同互质祖先的最近者,在这些不同值的祖先中,再取最近的祖先。
  • 即为所求。

 

对于DFS

  • 状态:
    • 当前node:i,值 nums[i]
    • 当前层次:level
    • 到目前为止的继承线: ancestor
  • 选择:
    • i 的所有子节点(所有相邻节点-父节点)

 

参考辅助信息:

  • 结果:res:各个节点的结果
  • 节点的相邻关系:graph:
    • 节点 i 的相邻节点有{a,b,c...},则graph[i]={a,b,c...}
      • 同时graph[a],graph[b],graph[c]也都分别含有 i。
  • 互质数关系:cops
    • 值 i,的互质数有 {值a,值b,值c...},则cops[i] = {a,b,c...}

 

代码参考:

 1 class Solution {
 2 public:
 3     //dfs:
 4     //记录一条继承关系下来的所有节点。ancestor:map: key:数值, vector<value>:层次+id 
 5     //对于当前节点 i
 6     //在其ancestor中,
 7     //对所有与num[i]互质的数值cop(list)中,找离他最近的祖先。
 8     //   对于同一个互质数cop[j], 离他最近的祖先:即是,最后一个加入ancestor的数。
 9     //   然后,对所有互质数,求最近的ancestor。
10     //状态:节点id: i, 节点值: num[i]
11     //     层次: level,
12     //     这一路的继承带:ancestor
13     //选择:所有相邻节点-**父节点**
14     unordered_map<int,vector<int>> cops;// key:num[i], value:{与key互质的所有数}
15     unordered_map<int,vector<pair<int, int>>> ancestor;
16     vector<vector<int>> graph;
17     void dfs(vector<int>& res, vector<int>& nums,
18              int i, int level,//state 
19              int parent) {//options
20         // for current node i
21         auto nearst_level = -1;//level
22         for(int onecop:cops[nums[i]]) {//for all 节点i的互质数
23             //for 祖先value=onecop 的所有祖先
24             if(ancestor[onecop].empty()) continue;//没有这样互质的祖先
25             auto [acst_level, acst_id] = ancestor[onecop].back();//有这个互质祖先,取最近
26             if(acst_level>nearst_level) {//各种互质数之间,有更近的,更新结果为最新的。
27                 nearst_level = acst_level;
28                 res[i] = acst_id;
29             }
30         }
31         //将当前节点加入祖先
32         ancestor[nums[i]].push_back({level, i});
33         //选择:所有孩子
34         for(int child:graph[i]) {
35             if(child==parent) continue;
36             dfs(res, nums, child, level+1, i);
37         }
38         //将当前节点弹出
39         ancestor[nums[i]].pop_back();
40         return;
41     }
42     vector<int> getCoprimes(vector<int>& nums, vector<vector<int>>& edges) {
43         unordered_set<int> s(begin(nums), end(nums));
44         vector<int> res(nums.size(),-1);
45         graph.resize(nums.size());
46         //create 互质 info
47         for(int i:s) {
48             for(int j:s) {
49                 if(__gcd(i,j)==1) cops[i].push_back(j);
50             }
51         }
52         //create graph
53         for(auto ed:edges) {
54             graph[ed[0]].push_back(ed[1]);
55             graph[ed[1]].push_back(ed[0]);
56         }
57         dfs(res, nums, 0, 0, 0);
58         return res;
59     }
60 };

 

posted @ 2021-03-17 15:42  habibah_chang  阅读(92)  评论(0编辑  收藏  举报