当前位置: 首页 > news >正文

力扣: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 仅由小写英文字母组成

对于这个题目我想了2种解法,文章主要讨论第二种方法。

思路1:

        第一种思路也是比较无脑的解法,把树当作特殊的无向图处理,由 parent 数组关系建立邻接表,遍历所有结点,对每个结点做 dfs,递归访问相邻结点,判断相邻结点和自身的字符是否相等,相等就终止并返回,不相等就继续递归搜索。走完整棵树的所有可能,最后求出答案,但这种解法的时间复杂度显然是极大的,结果就是时间超限。

参考代码:

class Solution {
public:static const int N = 1e5 + 10;static const int INF = 0x3f3f3f3f;vector<int> a[N];//邻接表建图int ans = -INF;bool vi[N];int longestPath(vector<int>& parent, string s) {memset(vi, 0, sizeof vi);int n = s.size();for (int i = 0;i < parent.size();i++) {int u = i;int v = parent[i];if (v == -1) {continue;}a[u].push_back(v);a[v].push_back(u);}for (int i = 0;i < n;i++) {vi[i] = 1;dfs(i, 1, s);vi[i] = 0;}return ans;}bool check(int x,string s) {for (auto it : a[x]) {if (!vi[it] && s[it] != s[x]) {//相邻结点未访问且字符与该节点不同return true;}}return false;}void dfs(int x,int sum, string s) {if (!check(x, s)) {ans = max(ans, sum);return;}for (auto it : a[x]) {if (!vi[it] && s[it] != s[x]) {vi[it] = 1;//标记访问dfs(it, sum + 1, s);vi[it] = 0;}}}
};

思路2:

树状dp,对于以x为根的树它的最长路径无非就是2种情况:

1、不经过x结点,整棵树的最长路径存在于x的某个子树内

2、经过x结点,整棵树的最长路径 = 从 x 结点出发到达子树的最大深度 + 第二大深度 + 1

因此我们需要每棵树的信息就是从根结点开始向下可到达的最大深度以及整棵树内部的最长路径,将这些信息在递归中返回给父节点,供父节点计算。

对于 x结点来说:如果该节点为叶子结点,他向下的最大深度和最长路径都只含自身,也就是1;如果该节点不为叶子结点,就访问其所有子节点,获取子节点(子树)的最长路径,如果子节点的字符与 x 结点字符不等,该条件下计算更新到达子节点的最大深度和第二大深度,获得这些信息后进行比较,上述的第一种情况就是获取的子树最长路径,而第二种情况也可通过计算得出。将两者的结果取最大值返回即可。 

AC代码:

C++版本:

class Solution {
public:typedef struct {int w;//以该节点为根的最长路径长度int len;//该结点向下的最大深度}Node;static const int N = 1e5 + 10;vector<int> a[N];int longestPath(vector<int>& parent, string s) {for (int i = 0;i < parent.size();i++) {int ch = i;int fa = parent[i];if (fa == -1) {continue;}a[fa].push_back(ch);}return fun(0, s).w;}Node fun(int x, string& s) {Node t;t.w = 1;t.len = 1;int dep1 = 0;int dep2 = 0;for (auto it : a[x]) {Node k = fun(it, s);if (s[x] != s[it]) {//该节点字符与子结点字符不等t.len = max(t.len, k.len + 1);//获取子树的最大深度if (dep1 <= k.len) {//获取子节点的最大和第二大深度dep2 = dep1;dep1 = k.len;}else if (dep2 < k.len) {dep2 = k.len;}}t.w = max(t.w, k.w);//获取子节点可分配的最长路径长度}t.w = max(t.w, dep1 + dep2 + 1);return  t;}
};

java版本:

import java.util.ArrayList;class Solution {class Node{int w;int len;public Node() {}public Node(int w, int len) {this.w = w;this.len = len;}}public final int N=100010;public ArrayList<Integer>[] a=new ArrayList[N];public int longestPath(int[] parent, String s) {int n=parent.length;for (int i = 0; i < n; i++) {a[i]=new ArrayList<>();}for (int i = 0; i < parent.length; i++) {int ch=i;int fa=parent[i];if(fa==-1){continue;}a[fa].add(ch);}return fun(0,s).w;}public Node fun(int x,String s){Node t=new Node(1,1);if(a[x].isEmpty()){return t;}int dep1=0;int dep2=0;for (int i = 0; i < a[x].size(); i++) {Node k=fun(a[x].get(i),s);if(s.charAt(x)!=s.charAt(a[x].get(i))) {t.len = Math.max(t.len, k.len + 1);if (dep1 <= k.len) {dep2 = dep1;dep1 = k.len;} else if (dep2 < k.len) {dep2 = k.len;}}t.w=Math.max(t.w,k.w);}t.w=Math.max(t.w,dep1+dep2+1);return t;}
}

http://www.xdnf.cn/news/1244701.html

相关文章:

  • ESP-idf框架下的HTTP服务器\HTML 485温湿度采集并长传
  • 14.Home-新鲜好物和人气推荐实现
  • 编程算法:技术创新与业务增长的核心引擎
  • Linux操作系统从入门到实战(十三)版本控制器Git基础概念讲解
  • 深入浅出 RabbitMQ-路由模式详解
  • 自由学习记录(77)
  • 24. 前端-js框架-Vue
  • vite面试题及详细答案120题(01-30)
  • 【工程化】tree-shaking 的作用以及配置
  • 研发团队看板协作中的自动化实践:集成CI/CD与任务流转
  • 【Linux系统】进程间通信:基于匿名管道实现进程池
  • linux_https,udp,tcp协议(更新中)
  • C语言基础_随机数、数组、函数、指针
  • 【机器学习深度学习】模型压缩简介
  • C++ - 基于多设计模式下的同步异步日志系统(11w字)
  • NLP——BERT模型全面解析:从基础架构到优化演进
  • AWS EKS节点扩容时NLB与Ingress的故障处理与优化方案
  • LSTM + 自注意力机制:精准预测天气变化的创新方案
  • 深入剖析 RAG 检索系统中的召回方式:BM25、向量召回、混合策略全解析
  • JS-第二十一天-尺寸位置
  • Android UI 组件系列(十一):RecyclerView 多类型布局与数据刷新实战
  • AI 对话高效输入指令攻略(四):AI+Apache ECharts:生成各种专业图表
  • 【学习笔记】Manipulate-Anything(基于视觉-语言模型的机器人自动化操控系统)
  • 【09】C++实战篇——C++ 生成静态库.lib 及 C++调用lib,及实际项目中的使用技巧
  • javacc学习笔记 02、JavaCC 语法描述文件的格式解析
  • Druid手写核心实现案例 实现一个简单Select 解析,包含Lexer、Parser、AstNode
  • k8s常见问题
  • (论文速读)RMT:Retentive+ViT的视觉新骨干
  • 20250805问答课题-实现TextRank + 问题分类
  • 力扣热题100------21.合并两个有序链表