news 2026/5/29 0:50:22

千问 LeetCode 2791. 树中可以形成回文的路径数 Java实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
千问 LeetCode 2791. 树中可以形成回文的路径数 Java实现

这是一道经典的树上路径计数问题,结合了状态压缩和异或(XOR)的技巧。

核心思路

1. 回文判断条件:一个字符串的字符重新排列后能形成回文,当且仅当字符串中最多只有一个字符出现了奇数次,其余字符均出现偶数次。
2. 状态压缩与异或:由于字符串只包含小写字母(26个),我们可以用一个 26 位的二进制数(int 类型)来表示当前路径上各字符出现次数的奇偶性。某一位为 1 表示该字符出现了奇数次,为 0 表示出现了偶数次。在树上遍历时,向下走一条边相当于对该边字符对应的二进制位进行异或操作。
3. 路径转化:树上任意两点 u 到 v 的路径,可以看作是从 u 到根节点,再从根节点到 v 的路径。其中,从 u 和 v 的最近公共祖先(LCA)到根节点的这段路径被重复走了两次(一去一回),字符出现次数必然为偶数(异或后为0),不影响回文判断。因此,我们只需要记录每个节点到根节点的路径状态。
4. 计数逻辑:使用 DFS 遍历树,并用一个哈希表(HashMap)记录遍历过程中,各种路径状态出现的次数。对于当前节点,如果之前存在一个节点到根节点的状态与当前状态完全相同(异或结果为0,所有字符均为偶数次)或仅相差一位(异或结果只有一个1,仅一个字符为奇数次),那么这两个节点之间的路径就能形成回文。

Java 代码实现

import java.util.*;

class Solution {
public long countPalindromePaths(List<Integer> parent, String s) {
int n = parent.size();
// 1. 构建邻接表(树结构)
List<Integer>[] children = new ArrayList[n];
Arrays.setAll(children, e -> new ArrayList<>());
for (int i = 1; i < n; i++) {
int p = parent.get(i);
children[p].add(i);
}

// 2. 哈希表记录从根节点到当前路径的状态(异或值)出现的次数
// 初始放入 0:1,代表根节点之上的空路径状态
Map<Integer, Integer> count = new HashMap<>();
count.put(0, 1);

return dfs(0, 0, children, s.toCharArray(), count);
}

private long dfs(int node, int status, List<Integer>[] children, char[] chars, Map<Integer, Integer> count) {
long res = 0;

for (int child : children[node]) {
// 计算从根节点到子节点 child 的路径状态
// 异或上当前边上的字符对应的位
int childStatus = status ^ (1 << (chars[child] - 'a'));

// 情况1:之前有相同状态的路径(所有字符出现偶数次,异或后为0)
res += count.getOrDefault(childStatus, 0);

// 情况2:之前有仅相差一个字符奇偶性的路径(仅一个字符出现奇数次)
for (int i = 0; i < 26; i++) {
res += count.getOrDefault(childStatus ^ (1 << i), 0);
}

// 将当前子节点的状态加入哈希表,供后续节点匹配
count.put(childStatus, count.getOrDefault(childStatus, 0) + 1);

// 继续向下 DFS
res += dfs(child, childStatus, children, chars, count);
}
return res;
}
}

复杂度分析
* 时间复杂度:O(n * A),其中 n 是节点数量,A 是字符集大小(本题为26)。每个节点只会被遍历一次,每次遍历需要枚举 26 个字母来寻找只差一位的状态。
* 空间复杂度:O(n),主要用于存储树的邻接表以及哈希表。在最坏情况下(如链状树),哈希表可能存储 O(n) 个不同的状态。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/29 0:50:18

Qwen Max LeetCode 2813. 子序列最大优雅度 Java实现

哈哈&#xff0c;LeetCode 2813&#xff01;这道题可是 **2024 年 Meta&#xff08;Facebook&#xff09;周赛** 的压轴题&#xff0c;难度不小&#xff0c;但思路一旦打通就特别爽&#xff5e; 而且它和 2809 完全不同风格&#xff1a;**贪心 哈希 反悔策略**&#xff0c;…

作者头像 李华
网站建设 2026/5/29 0:47:07

深度评测:LaserGRBL开源激光雕刻控制软件的技术架构与性能分析

深度评测&#xff1a;LaserGRBL开源激光雕刻控制软件的技术架构与性能分析 【免费下载链接】LaserGRBL Laser optimized GUI for GRBL 项目地址: https://gitcode.com/gh_mirrors/la/LaserGRBL 在工业自动化和数字制造领域&#xff0c;激光雕刻控制软件作为连接设计创意…

作者头像 李华
网站建设 2026/5/29 0:44:01

ROS节点自启动踩坑实录:从startup application到systemd,我最终选择了它

ROS节点自启动终极指南&#xff1a;从图形界面到无头服务器的系统级解决方案凌晨三点的实验室&#xff0c;屏幕上的错误日志让我彻底清醒——又一次&#xff0c;精心设计的ROS导航系统在重启后变成了"植物人"。这不是第一次因为自启动配置失败而耽误演示&#xff0c;…

作者头像 李华
网站建设 2026/5/29 0:34:08

如何3分钟破解网易云音乐格式锁:ncmdump终极解密转换完整教程

如何3分钟破解网易云音乐格式锁&#xff1a;ncmdump终极解密转换完整教程 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 你是否曾在网易云音乐下载了心爱的歌曲&#xff0c;却发现在其他设备上无法播放&#xff1f;那个神秘的NCM格…

作者头像 李华
网站建设 2026/5/29 0:32:02

基于Arduino与SIM800C的简易手机DIY:从硬件设计到嵌入式编程全流程解析

1. 项目概述&#xff1a;从零打造你的第一台“功能机”几年前&#xff0c;我还在大学实验室里捣鼓各种单片机开发板时&#xff0c;就萌生过一个想法&#xff1a;能不能用这些简单的模块&#xff0c;自己攒出一台能打电话、发短信的手机&#xff1f;这听起来像是电子爱好者的“毕…

作者头像 李华