【刷题】Leetcode 1609.奇偶树

news2024/9/21 4:40:21

在这里插入图片描述

Leetcode 1609.奇偶树

  • 题目描述
    • 广度优先搜索(BFS)
    • 深度优先算法(DFS)
  • 思路一(BFS)
  • 思路二(DFS)
  • Thanks♪(・ω・)ノ谢谢阅读!!!
  • 下一篇文章见!!!

题目描述

在这里插入图片描述
根据题目信息,我们可以整理出一些基本思路。

  1. 首先我们需要想办法遍历每层数据 其中需要记录二叉树当前深度。
  2. 遍历的过程中进行判断,不符合要求就返回false

基本就需要做到这两大板块就可以完成我们的任务了。重要的是这个过程如何实现:这里我们用到两个常用方法:广度优先搜索 (BFS)和 深度优先搜索(DFS)。下面初步解释一下两种算法:

广度优先搜索(BFS)

广度优先搜索是连通图的一种遍历算法,是很多重要图算法的原型(比如Dijkstra最短路径算法和Prim最小生成树算法)。它是一种盲目搜索法,目的是展开并检查图中的所有节点,进而得到结果。
过程是十分暴力的,不考虑结果的具体位置,直接遍历搜索所有节点,直到找到结果为止。基本过程是从根节点开始,沿着树(图)遍历所有节点,访问完所以节点后算法终止。常使用队列(FIFO)辅助实现BFS算法。

深度优先算法(DFS)

深度优先算法是图论的经典算法,是针对图和树的遍历算法(比如前序遍历,中序遍历,后序遍历)。利用深度优先算法可以产生目标图的对应拓扑排序表,进而方便的解决问题(如最大路径算法)。
其过程简单来说是对一个可能分支进行处理到不能再进行处理为止。如果是死路就返回,返回图中遇见未探索的分支就进行进行处理,直到达到要求。一般使用堆或栈来辅助实现DFS算法。

思路一(BFS)

根据上面的介绍我们可以通过队列来辅助我们进行遍历所有树。
具体分为两个循环嵌套:

  1. 首先外围while 保证访问所有节点,并记录深度。
  2. 内层for循环 负责处理该层所有节点,并将下一层节点存入队列中。

接下来是一些细节:

  1. leve记录层数 (注意从0开始)
  2. prev 记录上一个节点数
  3. value记录当前节点数
  4. prev 处理完每个节点后 需要迭代。
  5. 每层处理结束后 level++
    这两个循环是算法的核心部分, 保证了遍历所有节点.
    来看代码实现(选择使用C++ 比较方便)
class Solution {
public:
    bool isEvenOddTree(TreeNode* root) {
        //建立队列
        queue<TreeNode*> qu;
        //先入根节点
        qu.push(root);
        //设置层数
        int level = 0;
		//开始遍历 队列全为空就结束
        while(!qu.empty()){
        	//prev 为前一个节点值 这里进行初始化
        	//偶数下标 层上的所有节点的值都是 奇整数,从左到右按顺序严格递增
        	//所以 prev设置为最小值
			//奇数下标 层上的所有节点的值都是 偶整数,从左到右按顺序严格递减
        	//所以 prev设置为最大值
            int prev = level % 2 == 0 ? INT_MIN : INT_MAX;
            //获取当前层节点个数
            int size = qu.size();
            //进入该层循环
            for(int i = 0 ; i < size ;i++){
				//出队列 得到节点
                TreeNode* node = qu.front();
                qu.pop();
				//获取当前节点值
                int value = node->val;
				//节点值 与 该层数奇偶不符 返回 false
                if(value % 2 == level % 2) return false;
                //偶数下标层 必须满足严格递增 通过当前值与上一个节点值进行判断
                if(level % 2 == 0 && value <= prev) return false;
                //奇数下标层 必须满足严格递减 通过当前值与上一个节点值进行判断
                if(level % 2 == 1 && value >= prev) return false;
				//进行入队列处理
                if(node->left) qu.push(node->left);
                if(node->right) qu.push(node->right);
				//该节点结束 先前节点值迭代
                prev = value;
            }
            //层数增加
            level++;
        }
        //全部满足条件 返回真即可
        return true;
    }
};

来看效果:
在这里插入图片描述
过啦!!! 大声欢呼!!!

思路二(DFS)

该思路使用递归,所以有点不太好理解,动态规划好DFS 的混合运算了属于。
我们写出的dfs函数主要完成以下工作:
bool dfs(TreeNode* root,int p)

  1. root 为当前节点 p 为层数 dp[ p ]储存该层最新的数值
  2. 首先判断是否满足基本条件:
    偶数下标 层上的所有节点的值都是 奇 整数,从左到右按顺序 严格递增
    奇数下标 层上的所有节点的值都是 偶 整数,从左到右按顺序 严格递减
    判断递增递减是通过 当前节点值与dp[ p ]的值进行比较
    满足条件就更新dp[ p ] 值
  3. 然后进行下一层的判断
  4. 直到处理完所有数据。
//设置常量 方便使用
const int N = 1e5 + 7;
const int MAX = 0x3f3f3f3f;
class Solution {
public:
	// dp[]数组储存上一个符合要求的值 
    int dp[N + 1];
    bool dfs(TreeNode* root,int p){
    	//记录当前节点值
        int value = root->val;
        //奇数下标层 必须满足严格递减 通过当前值与上一个节点值进行判断
        if(p & 1){
            if(value & 1 || value >= dp[p]) return false;
        }
        //偶数下标层 必须满足严格递增 通过当前值与上一个节点值进行判断
        else{
            if(!(value & 1) || value <= dp[p]) return false;
        }
        //满足条件就更新数组值
        dp[p] = value;
        //继续深入处理
        if(root->left && !dfs(root->left,p+1)) return false;
        if(root->right && !dfs(root->right,p+1)) return false;
        //符合要求 返回真
        return true;
    }
    bool isEvenOddTree(TreeNode* root) {
        for(int i = 0;i<N;i+=2) {
            dp[i] = 0;//偶数下标 需要递增所以使用最小值0
            dp[i + 1] = MAX;//奇数下标 需要递增所以使用最小值0
        }
        return dfs(root,0);
    }
};

来看效果:
在这里插入图片描述
过啦!!!!!!!!!!!!!!!!!!!

这道题是我目前做过最难的题,虽然没有一遍做出来,但是参考大佬的代码,慢慢啃的感觉的真的很好。刷题继续!!!!!!

Thanks♪(・ω・)ノ谢谢阅读!!!

下一篇文章见!!!

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

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

相关文章

配置之道:深入研究Netty中的Option选项

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 配置之道&#xff1a;深入研究Netty中的Option选项 前言Option的基础概念ChannelOption与Bootstrap Option常见的ChannelOption类型ChannelConfig的使用Option的生命周期不同传输协议的Option 前言 在…

【MySQL】MySQL复合查询--多表查询自连接子查询 - 副本

文章目录 1.基本查询回顾2.多表查询3.自连接4.子查询 4.1单行子查询4.2多行子查询4.3多列子查询4.4在from子句中使用子查询4.5合并查询 4.5.1 union4.5.2 union all 1.基本查询回顾 表的内容如下&#xff1a; mysql> select * from emp; ----------------------------…

Java——建造者模式(Builder)

建造者模式&#xff08;Builder&#xff09; 1、建造者模式的定义 将一个复杂对象的构建与它的表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。 Builder模式是一步一步创建一个复杂对象的创建型模式&#xff0c;它允许使用者在不知道内部建造细节的情况下&…

vue3的router

需求 路由组件一般放在&#xff0c;pages或views文件夹, 一般组件通常放在component文件夹 路由的2中写法 子路由 其实就是在News组件里面&#xff0c;再定义一个router-view组件 他的子组件&#xff0c;机会渲染在router-view区域 路由传参 <RouterLink :to"/news…

Charles抓包 - 安装、激活、证书配置

最近刚好又遇到了抓包的需求&#xff0c;之前一直使用 Fiddler 抓包&#xff0c;这几年一直听大家都在用 Charles 抓包&#xff0c;正好一起了解下&#xff08;一般建议掌握一种抓包方式即可&#xff0c;都可以解决同种需求场景&#xff09; 抓包 Fiddler抓包 Charles 下载、安…

Day08:基础入门-算法分析传输加密数据格式密文存储代码混淆逆向保护

目录 传输数据-编码型&加密型等 传输格式-常规&JSON&XML等 密码存储-Web&系统&三方应用 代码混淆-源代码加密&逆向保护 思维导图 章节知识点&#xff1a; 应用架构&#xff1a;Web/APP/云应用/三方服务/负载均衡等 安全产品&#xff1a;CDN/WAF/I…

HotFix原理学习

原文链接&#xff1a;Unity 游戏用XLua的HotFix实现热更原理揭秘-CSDN博客 本文通过对XLua的HoxFix使用原理的研究揭示出来这样的一套方法。这个方法的 第一步&#xff1a;通过对C#的类与函数设置Hotfix标签。来标识需要支持热更的类和函数。第二步&#xff1a;生成函数连接器…

94. 递归实现排列型枚举 刷题笔记

思路 依次枚举 每个位置用哪个数字 要求按照字典序最小来输出 而每次搜索下一层时i都是从1开始 也就是说 如果有小的数可以填上 那么该方案会填上这个数字 例如 当n等于3 第一次搜索 1 2 3输出后返回 返回后此时i3 第二个位置填3 1 3 2 输出后返回 此时返回到第一层…

tkinterFrame框架+标签框架LabelFrame+Toplevel窗口的使用

1.在tkinter中&#xff0c;Frame是一个容器小部件用于组织和管理其他小部件。它可以作为一个独立的可见区域&#xff0c;也可以作为其他小部件的父容器。 import tkinter as tk import tkinter.ttk as ttk import tkinter.messagebox as mbm tk.Tk() m.title("tkinter L…

C 嵌入式系统设计模式 16:循环执行模式

本书的原著为&#xff1a;《Design Patterns for Embedded Systems in C ——An Embedded Software Engineering Toolkit 》&#xff0c;讲解的是嵌入式系统设计模式&#xff0c;是一本不可多得的好书。 本系列描述我对书中内容的理解。本文章描述嵌入式并发和资源管理模式之二…

Linux进程管理:(二)进程调度原语

文章说明&#xff1a; Linux内核版本&#xff1a;5.0 架构&#xff1a;ARM64 参考资料及图片来源&#xff1a;《奔跑吧Linux内核》 Linux 5.0内核源码注释仓库地址&#xff1a; zhangzihengya/LinuxSourceCode_v5.0_study (github.com) 进程调度的概念比较简单&#xff0c…

倒模专用制作耳机壳UV树脂:改性丙烯酸树脂

倒模专用制作耳机壳的UV树脂是经过改性的丙烯酸树脂&#xff0c;具有高透明度、高粘度、快速固化的特点。这种树脂可以通过紫外线光固化&#xff0c;快速形成坚硬的表面&#xff0c;并且具有较高的硬度和耐磨性&#xff0c;因此非常适合用于制作耳机壳。 此外&#xff0c;改性丙…

面试经典 150 题 ---- 轮转数组

面试经典 150 题 ---- 轮转数组 轮转数组方法一&#xff1a;使用额外的数组方法二&#xff1a;数组翻转 轮转数组 方法一&#xff1a;使用额外的数组 我们可以使用额外的数组来将每个元素放至正确的位置。用 n 表示数组的长度&#xff0c;我们遍历原数组&#xff0c;将原数组…

Java SE:多线程(Thread)

1. 线程两个基本概念 并发&#xff1a;即线程交替运行多个指令并行&#xff1a;即多个线程同时运行指令 并发并行不矛盾&#xff0c;两者可同时发生&#xff0c;即多个线程交替运行指令 2. 多线程3种实现方式 2.1 直接创建线程对象 /*** 方式1&#xff1a;* 1. 创建thread类的…

MySQL表分区技术介绍

目录 1. 分区概述 1.1 表分区 1.2 表分区与分表的区别 1.3 表分区的好处 1.4 分区表的限制因素 2. 如何判断当前MySQL是否支持分区&#xff1f; 3. 分区类型详解 3.1 MySQL支持分区类型 3.2 RANGE分区 3.2.1 根据数值范围分区 3.2.2 根据TIMESTAMP范围分区 3.2.3 根…

鸿蒙Harmony应用开发—ArkTS声明式开发(点击事件)

组件被点击时触发的事件。 说明&#xff1a; 从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 onClick onClick(event: (event: ClickEvent) > void) 点击动作触发该回调。 卡片能力&#xff1a; 从API version 9开始…

Python列表的合并、重复、判断与切片操作你学会了吗

1.合并列表 通过 实现 list1 ["佛跳墙", "肠粉", "刀削面", "烤鸭"]list2 [32, 4, 5, 7.43, True]list3 list1 list2print(list3) # [佛跳墙, 肠粉, 刀削面, 烤鸭, 32, 4, 5, 7.43, True] 2.重复输出列表中的元素 通过 * 实…

webstorm 创建运行纯Typescript项目

创建一个空项目&#xff0c;在项目根目录创建一个tsconfig.json文件自动配置&#xff1a; 打开终端输入tsc --init&#xff0c;即可自动生成tsconfig.json文件手动配置&#xff1a; 在项目根目录下新建一个tsconfig.json文件,并配置如下内容 具体配置可以直接使用下面的配置&am…

动态规划(算法竞赛、蓝桥杯)--单调队列滑动窗口与连续子序列的最大和

1、B站视频链接&#xff1a;E11【模板】单调队列 滑动窗口最值_哔哩哔哩_bilibili 题目链接&#xff1a;滑动窗口 /【模板】单调队列 - 洛谷 #include <bits/stdc.h> using namespace std; const int N1000010; int a[N],q[N];//q存的是元素的下标 int main(){int n,k;…

【HTML】HTML基础4(超链接标签)

目录 超链接通用标签 链接分类及其使用 1.外部链接 ​编辑 2.内部链接 3.空链接 4.下载链接 超链接通用标签 <a href"跳转目标" target"目标窗口的弹出方式">文本或者图像</a> 用到的是&#xff1a;<a></a>双标签 其中 1. he…