LeetCode 5670. 互质树

该博客介绍了一种解决算法问题的方法,涉及树形结构和最大公约数(GCD)。给定一个节点值和边的树,任务是找到每个节点最近的互质祖先。通过深度优先搜索(DFS)策略,从根节点开始遍历,利用动态维护的桶结构记录节点值,从而高效地找到满足条件的祖先节点。解法中用到了动态规划和数论的知识,适用于数值范围较小的情况。
摘要由CSDN通过智能技术生成
题意:
给你一个 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 。

数据范围:
nums.length == n
1 <= nums[i] <= 50
1 <= n <= 105
edges.length == n - 1
edges[j].length == 2
0 <= uj, vj < n
uj != vj
解法:
观察到val的大小只有50,
从根开始dfs,50个桶记录dfs树链的所有值,
对于当前数x,直接[1,50]枚举值,判断祖先是否有这些值,
有的话更新答案即可.
code:
const int maxm=1e5+5;
vector<int>c[55];
vector<int>g[maxm];
int d[maxm];
vector<int>ans;
class Solution {
public:
    void dfs(vector<int>& a,int x,int fa){
        ans[x]=-1;
        for(int i=1;i<=50;i++){
            int len=c[i].size();
            if(len&&__gcd(a[x],i)==1){
                if(ans[x]==-1||d[ans[x]]<d[c[i][len-1]]){
                    ans[x]=c[i][len-1];
                }
            }
        }
        c[a[x]].push_back(x);
        for(int v:g[x]){
            if(v==fa)continue;
            d[v]=d[x]+1;
            dfs(a,v,x);
        }
        c[a[x]].pop_back();
    }
    vector<int> getCoprimes(vector<int>& a, vector<vector<int>>& e) {
        //init
        int n=a.size();
        for(int i=1;i<=50;i++)c[i].clear();
        memset(d,0,sizeof d);
        ans=vector<int>(n,0);
        for(int i=0;i<n;i++)g[i].clear();
        //
        for(auto i:e){
            int x=i[0],y=i[1];
            g[x].push_back(y);
            g[y].push_back(x);
        }
        dfs(a,0,0);
        return ans;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值