leetcode 2246. 相邻字符不同的最长路径

2246. 相邻字符不同的最长路径

给你一棵 树(即一个连通、无向、无环图),根节点是节点 0 ,这棵树由编号从 0 到 n - 1 的 n 个节点组成。用下标从 0 开始、长度为 n 的数组 parent 来表示这棵树,其中 parent[i] 是节点 i 的父节点,由于节点 0 是根节点,所以 parent[0] == -1 。

另给你一个字符串 s ,长度也是 n ,其中 s[i] 表示分配给节点 i 的字符。

请你找出路径上任意一对相邻节点都没有分配到相同字符的 最长路径 ,并返回该路径的长度。

示例 1:

输入:parent = [-1,0,0,1,1,2], s = “abacbe”
输出:3
解释:任意一对相邻节点字符都不同的最长路径是:0
-> 1 -> 3 。该路径的长度是 3 ,所以返回 3 。 可以证明不存在满足上述条件且比 3 更长的路径。
在这里插入图片描述

示例 2:

输入:parent = [-1,0,0,0], s = “aabc”
输出:3
解释:任意一对相邻节点字符都不同的最长路径是:2 -> 0
-> 3 。该路径的长度为 3 ,所以返回 3 。

在这里插入图片描述

提示:

n == parent.length == s.length
1 <= n <= 105 对所有 i >= 1 ,
0 <= parent[i] <= n - 1 均成立
parent[0] == -1 parent 表示一棵有效的树 s 仅由小写英文字母组成

解析:
1,将父节点表示的树形式,转换为图的形式,邻接链表
2,通过dfs遍历邻接链表,找出符合条件的最长路径
3,本题和leetcode124相似,但是124是二叉树形式,本题为多叉树形式,并且最大路径中相邻结点不能重合。
124题解
4,因此需要处理多叉情况,多叉和二叉的最长路径是一样的,每个结点对应的最大值都是本结点最长的两个孩子结点加上其本身,只不过二叉树中就两个孩子结点,多叉树中找到其最大的两个孩子即可。
5,针对相邻结点不能重复情况,遇到相同的孩子结点,只需要dfs他的孩子结点即可(为了找出其孩子结点为根的子树的最长路径),并不需要使用找个孩子结点的返回值。
下图对应5

ab
返回值与最长路径的区别
结点1作为根节点,最大长度为3,但是1作为0的子节点返回时只能返回2,因为从0-1-3/0-1-4,而不可以0-1-3-1-4。
在这里插入图片描述

code:

class Solution {
public:
    int ans=1;
    int dfs(vector<vector<int>>& g,string& s ,int cur){
        int a =0;
        int b =0;
        for(int i=0;i<g[cur].size();i++){
            int c= dfs(g,s,g[cur][i]);
            if(s[g[cur][i]]==s[cur])
                continue;
            // 符合条件的最大孩子路径长度
            if(c>a){
                b=a;
                a=c; 
            }else if(c>b){
                b=c;
            }
        }
        // 最大值和返回值并不相同,当前结点的返回值是最长孩子和本身
        // 最大值是以当前结点为根的最长路径,包括两个最长孩子和本身
        ans = max(ans,b+a+1);
        return a+1;
    }
    int longestPath(vector<int>& parent, string s) {
        //将树变成图
        int n=parent.size();
        vector<vector<int>> g(n);
        for(int i=1;i<n;i++){
            g[parent[i]].push_back(i);
        }
        dfs(g,s,0);
        return ans;
    }
};

如果觉得还可以的,希望点个免费的鼓励一下。

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值