统计二叉树中的伪回文路径 : 用位运用来加速??

题目描述

这是 LeetCode 上的 「1457. 二叉树中的伪回文路径」 ,难度为 「中等」

Tag : 「DFS」、「位运算」

给你一棵二叉树,每个节点的值为 19

我们称二叉树中的一条路径是 「伪回文」的,当它满足:路径经过的所有节点值的排列中,存在一个回文序列。

请你返回从根到叶子节点的所有路径中伪回文路径的数目。

示例 1: alt

输入:root = [2,3,1,3,1,null,1]

输出:2 

解释:上图为给定的二叉树。总共有 3 条从根到叶子的路径:红色路径 [2,3,3] ,绿色路径 [2,1,1] 和路径 [2,3,1] 。
     在这些路径中,只有红色和绿色的路径是伪回文路径,因为红色路径 [2,3,3] 存在回文排列 [3,2,3] ,绿色路径 [2,1,1] 存在回文排列 [1,2,1] 。

示例 2: alt

输入:root = [2,1,1,1,3,null,null,null,null,null,1]

输出:1 

解释:上图为给定二叉树。总共有 3 条从根到叶子的路径:绿色路径 [2,1,1] ,路径 [2,1,3,1] 和路径 [2,1] 。
     这些路径中只有绿色路径是伪回文路径,因为 [2,1,1] 存在回文排列 [1,2,1] 。

示例 3:

输入:root = [9]

输出:1

提示:

  • 给定二叉树的节点数目在范围

DFS + 位运算

“伪回文”是指能够通过重新排列变成“真回文”,真正的回文串只有两种情况:

  • 长度为偶数,即出现次数为奇数的字符个数为
  • 长度为奇数,即出现次数为奇数的字符个数为 个(位于中间)

因此,「我们只关心路径中各个字符(数字 0-9)出现次数的奇偶性,若路径中所有字符出现次数均为偶数,或仅有一个字符出现次数为奇数,那么该路径满足要求」

节点值范围为 ,除了使用固定大小的数组进行词频统计以外,还可以使用一个 int 类型的变量 cnt 来统计各数值的出现次数奇偶性:若 的第 位为 ,说明数值 的出现次数为奇数,否则说明数值 出现次数为偶数或没出现过,两者是等价的。

例如 代表数值 和数值 出现次数为奇数次,其余数值没出现过或出现次数为偶数次。

翻转一个二进制数字中的某一位可使用「异或」操作,具体操作位 cnt ^= 1 << k

判断是否最多只有一个字符出现奇数次的操作,也就是判断一个二进制数字是为全为 或仅有一位 ,可配合 lowbit 来做,若 cntlowbit(cnt) = cnt & -cnt 相等,说明满足要求。

考虑到对 lowbit(x) = x & -x 不熟悉的同学,这里再做简单介绍:*lowbit(x) 表示 x 的二进制表示中最低位的 所在的位置对应的值*,即仅保留从最低位起的第一个 ,其余位均以 填充:

  • x = 6,其二进制表示为 ,那么
  • x = 12,其二进制表示为 ,那么

Java 代码:

class Solution {
    int ans = 0;
    public int pseudoPalindromicPaths (TreeNode root) {
        dfs(root, 0);
        return ans;
    }
    void dfs(TreeNode root, int cnt) {
        if (root.left == null && root.right == null) {
            cnt ^= 1 << root.val;
            if (cnt == (cnt & -cnt)) ans++;
            return ;
        }
        if (root.left != null) dfs(root.left, cnt ^ (1 << root.val));
        if (root.right != null) dfs(root.right, cnt ^ (1 << root.val));
    }
}

C++ 代码:

class Solution {
public:
    int ans;
    int pseudoPalindromicPaths(TreeNode* root) {
        dfs(root, 0);
        return ans;
    }
    void dfs(TreeNode* root, int cnt) {
        if (!root->left && !root->right) {
            cnt ^= 1 << root->val;
            if (cnt == (cnt & -cnt)) ans++;
            return;
        }
        if (root->left) dfs(root->left, cnt ^ (1 << root->val));
        if (root->right) dfs(root->right, cnt ^ (1 << root->val));
    }
};

Python 代码:

class Solution:
    def pseudoPalindromicPaths (self, root: Optional[TreeNode]) -> int:
        ans = 0
        def dfs(root, cnt):
            nonlocal ans
            if not root.left and not root.right:
                cnt ^= 1 << root.val
                ans += 1 if cnt == (cnt & -cnt) else 0
                return 
            if root.left:
                dfs(root.left, cnt ^ (1 << root.val))
            if root.right:
                dfs(root.right, cnt ^ (1 << root.val))
        dfs(root, 0)
        return ans

TypeScript 代码:

function pseudoPalindromicPaths (root: TreeNode | null): number {
    let ans = 0;
    const dfs = function (root: TreeNode, cnt: number): void {
        if (root.left == null && root.right == null) {
            cnt ^= 1 << root.val;
            if (cnt == (cnt & -cnt)) ans++;
            return ;
        }
        if (root.left) dfs(root.left, cnt ^ (1 << root.val));
        if (root.right) dfs(root.right, cnt ^ (1 << root.val));
    }
    dfs(root, 0);
    return ans;
};
  • 时间复杂度:
  • 空间复杂度:

最后

这是我们「刷穿 LeetCode」系列文章的第 No.1457 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。

在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。

为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode 。

在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。

更多更全更热门的「笔试/面试」相关资料可访问排版精美的 合集新基地 🎉🎉

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/168511.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Python的turtle模块绘制彩色螺旋线

1.1引言&#xff1a; 在Python中&#xff0c;turtle模块是一个非常有趣且强大的工具&#xff0c;它允许我们以一个可视化和互动的方式学习编程。在本博客中&#xff0c;我们将使用turtle模块来绘制一个彩色的螺旋线。通过调用各种命令&#xff0c;我们可以引导turtle绘制出指定…

Vue项目实战之一----实现分类弹框效果

效果图 实现 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><script src"js/vue.js"></script><!-- 引入样式 --><link rel"stylesheet&qu…

leetcode:随机链表的复制

题目描述 题目链接&#xff1a;138. 随机链表的复制 - 力扣&#xff08;LeetCode&#xff09; 题目分析 这个题目很长&#xff0c;但是意思其实很简单&#xff1a;就是一个单链表&#xff0c;每个结点多了一个指针random随机指向链表中的任意结点或者NULL&#xff0c;我们血需…

Linux后台运行Python的py文件,如何使ssh工具退出后仍能运行

常规运行 python3 mysqlbak.py ssh工具退出后&#xff0c;或ctrlc中断后&#xff0c;程序将不在运行 后台运行 nohup python3 mysqlbak.py > mysqlbak.log & > mysqlbak.log为可选项&#xff0c;输出日志到指定文件&#xff0c;如果不写&#xff0c;输出日志到nohup…

【Mysql学习笔记】3 - 本章作业

1.判断 1. 这句话表示ename as name 可以不要这个as&#xff0c;同理后面的sal salary也是别名&#xff0c;而选项D的Annual Salary中间也有空格&#xff0c;程序会判断为as 但as不能连用&#xff0c;所以错误&#xff0c;选D 2.选B&#xff0c;因为null不能加上判断符号<&…

oracle rac环境归档日志清除

文章目录 一、处理步骤1、使用终端登录上服务器查看磁盘使用状态2、使用恢复备份管理工具RMAN删除归档日志 二、详细操作步骤三、定时任务自动清归档日志1、编写删除脚本4、测试脚本运行情况5、设置定时任务每周执行一次&#xff0c;并测试运行效果 昨天单位的所有系统都连不上…

JoyT的科研之旅第一周——科研工具学习及论文阅读收获

CiteSpace概述 CiteSpace 是一个用于可视化和分析科学文献的工具&#xff0c;它专门针对研究者进行文献回顾和趋势分析。CiteSpace 的核心功能是创建文献引用网络&#xff0c;这些网络揭示了研究领域内各个文献之间的相互关系。使用 CiteSpace 可以为论文研究做出贡献的几种方…

激光塑料透光率检测仪进行材料质量监控

焊接质量检测是对焊接成果的检测&#xff0c;目的是保证焊接结构的完整性、可靠性、安全性和使用性。焊接质量检测通常包括外观检验、内部检查、无损检测以及试件制作与送检等步骤。通过这些检测方法&#xff0c;可以全面评估焊接质量&#xff0c;确保其符合设计要求和规范标准…

jenkins + gitlab 自动部署(webhook)

Jenkins是一个流行的开源CI/CD工具&#xff0c;可以与Git等版本控制系统集成&#xff0c;实现自动构建、测试和部署。Webhook是一种机制&#xff0c;可以在Git仓库中设置&#xff0c;在代码提交或合并请求时触发Jenkins构建任务&#xff0c;以完成自动化部署。 实操 设备信息 …

Linux常用命令——bind命令

在线Linux命令查询工具 bind 显示或设置键盘按键与其相关的功能 补充说明 bind命令用于显示和设置命令行的键盘序列绑定功能。通过这一命令&#xff0c;可以提高命令行中操作效率。您可以利用bind命令了解有哪些按键组合与其功能&#xff0c;也可以自行指定要用哪些按键组合…

【Unity3D】MAX聚合广告SDK——Pangle广告接入

Pangle, App Monetization Simplified 注册 登录 创建应用 创建广告单元 将其应用ID和广告ID关联到MAX广告。 下载Pangle Unity Plugin包&#xff0c;新建一个空工程&#xff08;很重要&#xff09; Unity版本2019.4.0f1 gradle plugin 4.2.0 gradle版本6.7.1 build_tools 34.…

golang panic关键词执行原理与代码分析

使用的go版本为 go1.21.2 首先我们写一个简单的panic调度与捕获代码 package mainfunc main() {defer func() {recover()}()panic("panic test") }通过go build -gcflags -S main.go获取到对应的汇编代码 可以看到当我们调度panic时&#xff0c;Go的编译器会将这段…

数据链路层-以太网协议

目录 数据链路层的作用认识以太网以太网帧格式认识MAC地址对比理解MAC地址和IP地址认识MTUMTU对UDP协议的影响MTU对TCP协议的影响数据跨网络传输的过程ARP协议ARP协议作用ARP数据报的格式ARP协议的工作流程 数据链路层的作用 我们知道数据能在网络中从一台主机发送到另一台主机…

JavaScript字符串操作指南:跨行表示与模板字面量

背景: 在 JavaScript 中&#xff0c;如果一个字符串需要跨行表示&#xff0c;你可以使用多种方式来实现。 实现&#xff1a; 法一&#xff1a; 使用反斜杠&#xff08;\&#xff09;进行换行续行&#xff1a; let str "这是一个跨行的字符串&#xff0c;\ 我在这里使…

Windows核心编程 进程间通信

目录 进程间通信概述 发送消息 WM_COPYDATA DLL共享段 文件映射 文件相关API CreateFile ReadFile WriteFile CloseHandle SetFilePointerEx 设置文件指针 获取文件大小 GetFileSize 结构体 LARGE_INTEGER 文件映射用于读写文件数据 文件映射用于进程间通信(带文…

UVA437 巴比伦塔 The Tower of Babylon

UVA437 巴比伦塔 The Tower of Babylon 题面翻译 题目描述 你可能已经听说过巴比伦塔的传说。现在这个传说的许多细节已经被遗忘。所以本着本场比赛的教育性质&#xff0c;我们现在会告诉你整个传说&#xff1a; 巴比伦人有 n n n 种长方形方块&#xff0c;每种有无限个&a…

使用Pytorch从零开始构建Conditional PixelCNN

条件 PixelCNN PixelCNN 是 PixelRNN 的卷积版本&#xff0c;它将图像中的像素视为一个序列&#xff0c;并在看到前面的像素后预测每个像素&#xff08;定义如上和左&#xff0c;尽管这是任意的&#xff09;。PixelRNN 是图像联合先验分布的自回归模型&#xff1a; p ( x ) …

【开源】基于Vue和SpringBoot的食品生产管理系统

项目编号&#xff1a; S 044 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S044&#xff0c;文末获取源码。} 项目编号&#xff1a;S044&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 加工厂管理模块2.2 客户管理模块2.3…

【Proteus仿真】【STM32单片机】智能垃圾桶设计

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真STM32单片机控制器&#xff0c;使用报警模块、LCD1602液晶模块、按键模块、人体红外传感器、HCSR04超声波、有害气体传感器、SG90舵机等。 主要功能&#xff1a; 系统运行后&…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《基于Fisher时段划分的配电网源网荷储多时间尺度协调优化调控策略》

这个标题涉及到电力系统领域的一些关键概念和方法。让我们逐步解读&#xff1a; 基于Fisher时段划分&#xff1a; "基于"表示这个策略或方法的核心基础是某个特定的理论或技术。"Fisher时段划分"可能指的是使用Fisher信息矩阵进行时间划分。Fisher信息矩阵…