《二叉树》——4(Leetcode题目练习)

news2024/11/22 16:19:43

目录

前言:

题目一:《对称二叉树》

思路:

 题目二:《单值二叉树》

思路:

题目三:《检查两颗树是否相同》 

思路:

题目四:《前序遍历》

思路:

题目五:《另一颗子树》

 思路:

题目六:《翻转二叉树》

  思路:

题目七:《平衡二叉树》

 思路:


前言:

本文将引出13道经典二叉树题目来帮助我们对于递归有更进一步学习。不仅能够锻炼我们对二叉树的理解,也能强化我们对递归算法的理解。一下是本文将涉及的题目:

《对称二叉树》《单值二叉树》《相同的树》《前序遍历》《另一颗子树》《翻转二叉树》《平衡二叉树》

题目一:《对称二叉树》

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

bool _isSymmetric(struct TreeNode* root1, struct TreeNode* root2)
{
    if(root1 == NULL && root2 == NULL)
        return true;
    
    if(root1 == NULL || root2 == NULL)
        return false;
    
    if(root1->val != root2->val)
        return false;
    

    return (_isSymmetric(root1->left, root2->right)) && (_isSymmetric(root1->right, root2->left));

}

bool isSymmetric(struct TreeNode* root) {
    return _isSymmetric(root->left, root->right);   
}

思路:

首先我们需要知道这道题目的分治子问题,

1、根节点的左子树和右子树比较

2、分两次比较,左子树右节点右子树左节点比较,左子树左节点右子树右节点比较

 

 

 题目二:《单值二叉树》

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
bool isUnivalTree(struct TreeNode* root) {
    if(!root)
    {
        return true;
    }

    if(root->left)
    {
        if(root->val != root->left->val)
        {
            return false;
        }
    }
    if(root->right)
    {
        if(root->val != root->right->val)
        {
            return false;
        }
    }

    return isUnivalTree(root->left) && isUnivalTree(root->right);

}

思路:

同样是找分治子问题。

1、空节点不影响其它节点,所以当访问到空节点时直接return true即可

2、将左孩子的值与自己的值相比,再将右孩子的值与自己相比。

题目三:《检查两颗树是否相同》 

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
bool isSameTree(struct TreeNode* p, struct TreeNode* q) {
    
    if((p==NULL && q != NULL) || (q == NULL && p!= NULL))
    {
        return false;
    }

    if(p == NULL && q == NULL)
    {
        return true;
    }

    if(p->val == q->val)
    {
       return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
    }

    return false;

}

思路:

1、如果p为空且q不为空,或者,p不为空且q为空。return false;

2、如果两个节点都为空,则直接return true;

3、如果当前节点均不为空,则比较值如果相同那么,左子树和左子树比较,右子树和右子树比较

题目四:《前序遍历》

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */

int TreeSize(struct TreeNode* root)
{
    return (root == NULL)?0:TreeSize(root->left) + TreeSize(root->right) + 1;
}

void Preorder(struct TreeNode* root, int* a, int* pi)
{
    if(root == NULL)
    {
        return;
    }

    a[(*pi)++] = root->val;
    Preorder(root->left, a, pi);
    Preorder(root->right, a, pi);
    

}

int* preorderTraversal(struct TreeNode* root, int* returnSize) {
    int n = TreeSize(root);
    int* a = (int*)malloc(sizeof(int)*n);
    *returnSize = n;
    int i = 0;
    Preorder(root, a, &i);
    return a;
    
}

思路:

 本题目有几个点需要注意:

1、题目明确说明:“* Note: The returned array must be malloced, assume caller calls free().”

意思就是说作返回值的数组,必须要malloc开辟的

2、关于形参中的“int* returnSize”,并不是一个数组,它是统计数的节点个数,需要我们求出数的节点个数并改变returnSize。

我们都知道想要交换两个变量,利用函数应当传递地址而不是传递值,因为形参是实参的一份临时拷贝。

再说回思路。

首先,既然是返回数组,那么我们需要对树进行一次前序遍历,将每次经过的非空节点的val存放到我们开辟好的数组中,并且改变returnSize即可。

我们在之前讲解《链式二叉树》的blog中,有实现创建关于“统计节点数”的函数,在这里我就不过多赘述。

当我们开辟好数组后,同样通过我上面所讲解的,对于函数传递地址既可以真正改变变量的值。

所以我们设i为数组的下标那么我们在调用前序遍历void Preorder(struct TreeNode* root, int* a, int* pi)函数则需要利用指针来接受。

再通过前序遍历的基本思路即可完成本题目。

题目五:《另一颗子树》

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */


bool compare(struct TreeNode* root, struct TreeNode* subRoot)
{
    if(root == NULL && subRoot == NULL)
    {
        return true;
    }
    if(root == NULL || subRoot == NULL)
    {
        return false;
    }
    if(root->val != subRoot ->val)
    {
        return false;
    }
    return compare(root->left, subRoot->left) && compare(root->right, subRoot->right);
}

bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot){
    if(root == NULL)
    {
        return false;
    }

    return compare(root, subRoot) || isSubtree(root->left,subRoot)||isSubtree(root->right,subRoot);


}

 思路:

1、比较两树根节点

2、若根节点相同则比较左子树再比较右子树

思路简单,但是在return 控制条件时较难理解。

 

题目六:《翻转二叉树》

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

 

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
struct TreeNode* invertTree(struct TreeNode* root) {
    if(root == NULL)
    {
        return NULL;
    }

    struct TreeNode* left = invertTree(root->left);
    struct TreeNode* right = invertTree(root->right);
    root->left = right;
    root->right = left;
    return root;
}

  思路:

分别将左右子树各个节点的左右孩子进行交换,从下往上

       


题目七:《平衡二叉树》

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

 

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

int TreeHeight(struct TreeNode* root)
{
	if (root == NULL)
	{
		return 0;
	}
	int leftheight = TreeHeight(root->left);
	int rightheight = TreeHeight(root->right);
	return (leftheight > rightheight) ? (leftheight + 1) : (rightheight + 1);
}

bool isBalanced(struct TreeNode* root) {
    if(root == NULL)
        return true;
    
    return fabs(TreeHeight(root->left) - TreeHeight(root->right))<=1 && isBalanced(root->left) && isBalanced(root->right);
}

 思路:

题目有句话说到,

意思就是说每个节点我们都需要判断。

1、我们求出根节点的左子树的高度,右子树的高度,相减。

2、相减之后的绝对值小于等于1那么就return true。

3、但是如果是一下这种情况:

 

对于根节点来说确实已经是平衡

但是对于2这个节点来说,就不是平衡了,因此return false

 

 

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

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

相关文章

CTFshow web(php命令执行 55-59)

web55 <?php /* # -*- coding: utf-8 -*- # Author: Lazzaro # Date: 2020-09-05 20:49:30 # Last Modified by: h1xa # Last Modified time: 2020-09-07 20:03:51 # email: h1xactfer.com # link: https://ctfer.com */ // 你们在炫技吗&#xff1f; if(isset($_GET[…

CVE-2022-25578 漏洞复现

CVE-2022-25578 路由/admin/admin.php是后台&#xff0c;登录账号和密码默认是admin、tao&#xff0c;选择文件管理。 是否还记得文件上传中的.htaccess配置文件绕过发&#xff0c;在这个文件中加入一句AddType application/x-httpd-php .jpg&#xff0c;将所有jpg文件当作php…

【后端高频面试题--设计模式下篇】

&#x1f680; 作者 &#xff1a;“码上有前” &#x1f680; 文章简介 &#xff1a;后端高频面试题 &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; 后端高频面试题--设计模式下篇 后端高频面试题--设计模式上篇设计模式总览模板方法模式怎么理解模…

大华智慧园区综合管理平台 deleteFtp RCE漏洞复现

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…

【深度学习】基于多层感知机的手写数字识别

案例2&#xff1a;构建自己的多层感知机: MNIST手写数字识别 相关知识点: numpy科学计算包&#xff0c;如向量化操作&#xff0c;广播机制等 1 任务目标 1.1 数据集简介 ​ MNIST手写数字识别数据集是图像分类领域最常用的数据集之一&#xff0c;它包含60,000张训练图片&am…

13.rk3588搭建rknn环境

一、搭建Anaconda3环境 首先下载Anaconda3-2022.10-Linux-aarch64.sh&#xff0c;链接&#xff1a;https://pan.baidu.com/s/10oXSAaleAEoe6KaJ3IQyaw &#xff0c;提取码&#xff1a;mtag 。 下载后放入到自己的home文件夹下面&#xff0c;然后在该文件夹下运行 bash Anaco…

深入学习《大学计算机》系列之第1章 1.7节——图灵机的一个例子

一.欢迎来到我的酒馆 第1章 1.7节&#xff0c;图灵机的一个例子。 目录 一.欢迎来到我的酒馆二.图灵机2.1 艾伦-图灵简介2.2 图灵机简介 三.图灵机工作原理3.1 使用图灵机打印二进制数3.2 图灵机工作原理总结 四.总结 二.图灵机 本节内容主要介绍计算机科学之父——艾伦-图灵、…

vue核心技术(二)

◆ 指令补充 指令修饰符 通过 "." 指明一些指令 后缀&#xff0c;不同 后缀 封装了不同的处理操作 → 简化代码 v-bind 对于样式控制的增强 为了方便开发者进行样式控制&#xff0c; Vue 扩展了 v-bind 的语法&#xff0c;可以针对 class 类名 和 style 行内样式…

第76讲安全退出实现

安全退出实现 VueX 是一个专门为 Vue.js 应用设计的状态管理构架&#xff0c;统一管理和维护各个vue组件的可变化状态(你可以理解成 vue 组件里的某些 data )。 Vuex有五个核心概念&#xff1a; state, getters, mutations, actions, modules。 state&#xff1a;vuex的基本数…

全国计算机技术与软件专业技术资格(水平)考试软考中级高级报名步骤

第一步&#xff1a; 1、登陆全国的计算机网上报名平台 http://bm.ruankao.org.cn/sign/welcome 根据自己所在地区&#xff0c;选择报考城市入口&#xff08;例如&#xff1a;北京考区考生&#xff0c;直接选择北京就 可以&#xff09; 第二步&#xff1a;用户登录 1、已有…

线性判别分析(LDA)

一、说明 LDA 是一种监督降维和分类技术。其主要目的是查找最能分隔数据集中两个或多个类的特征的线性组合。LDA 的主要目标是找到一个较低维度的子空间&#xff0c;该子空间可以最大限度地区分不同类别&#xff0c;同时保留与歧视相关的信息。 LDA 是受监督的&#xff0c;这意…

Mom系统初步认知

什么是MOM系统? MOM指制造运营管理,是Manufacturing Operation Management的缩写;指通过协调管理企业的人员、设备、物料和能源等资源,把原材料或零件转化为产品的活动。MOM系统集成了生产计划、库存管理、生产调度、质量管理、设备维护、人员管理等功能,以实现生产效率和…

web前端项目-进击的玉兔【附源码】

进击的玉兔 【进击的玉兔】是一款基于Web前端技术的游戏&#xff0c;其主题和背景与中国的传统文化和神话有关。在游戏中&#xff0c;玩家需要通过解决各种难题和挑战来收集月饼&#xff0c;最终达成游戏目标。 运行效果&#xff1a; HTML源码&#xff1a; <!DOCTYPE h…

Android13新特性之预测返回手势

Android14新特性之预测返回手势 简介 Android 14引入了对预测性返回手势的支持&#xff0c;这意味着开发者可以通过系统提供的额外动画和API来实现定制化的动画效果。这一更新使得应用程序可以在用户执行返回手势时展示一个动画预览&#xff0c;例如在应用程序前显示Home屏幕…

Makefile编译原理 make 中的路径搜索_2

一.make中的路径搜索 VPATH变量和vpath关键字同时指定搜索路径。 实验1 VPATH 和 vpath 同时指定搜索路径 mhrubuntu:~/work/makefile1/18$ tree . ├── inc │ └── func.h ├── main.c ├── makefile ├── src1 │ └── func.c └── src2 └── func.c mak…

FRP内网穿透如何避免SSH暴力破解(二)——指定地区允许访问

背景 上篇文章说到&#xff0c;出现了试图反复通过FRP的隧道&#xff0c;建立外网端口到内网服务器TCP链路的机器人&#xff0c;同时试图暴力破解ssh。这些连接造成了流量的浪费和不必要的通信开销。考虑到服务器使用者主要分布在A、B、C地区和国家&#xff0c;我打算对上一篇…

万维网的文档

目录 1 万维网的文档 动态万维网文档 CGI CGI 网关程序 活动万维网文档 用 Java 语言创建活动文档 1 万维网的文档 分为&#xff1a; 静态万维网文档。内容不会改变。简单。(html、xml、css) 动态万维网文档。文档的内容由应用程序动态创建。 活动万维网文档。由浏览器端…

npm config set registry https://registry.npm.taobao.org 这个设置了默认的镜像源之后如何恢复默认的镜像源

要恢复npm默认的镜像源&#xff0c;你可以使用以下命令将registry设置回npm的官方源&#xff1a; npm config set registry https://registry.npmjs.org/这个命令会修改你的全局npm配置&#xff0c;将包的下载源改回npm官方的源。这样做之后&#xff0c;任何后续的npm install…

【二叉树】层序遍历

目录 层序遍历概念&结构 层序遍历的实现 整体思路 代码实现 图示理解 BT升级 整体思路 代码实现 图示理解​ 应用 题目 前序&中序&后序遍历&#xff1a;深度优先遍历dfs 层序遍历&#xff1a;广度优先遍历bfs 层序遍历概念&结构 层序遍历&#xf…

【java语言基础⑥】面向对象——面向对象的思想、类与对象

1.学习目标 了解面向对象的思想&#xff0c;能够说出面向对象的三个特性掌握类的定义&#xff0c;能够独立完成类的定义掌握对象的创建和使用&#xff0c;能够完成对象创建&#xff0c;用对象访问对象属性和方法掌握对象的引用传递&#xff0c;能够独立实现对象的引用传递熟悉…