【算法与数据结构】98、LeetCode验证二叉搜索树

news2024/11/24 1:50:01

文章目录

  • 一、题目
  • 二、解法
  • 三、完整代码

所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。

一、题目

在这里插入图片描述
在这里插入图片描述

二、解法

  思路分析:注意不要落入下面你的陷阱,笔者本来想左节点键值<中间节点键值<右节点键值即可,写出如下代码:

class Solution2 {
public:
    // 1、输入参数, 返回值为result,以引用方式传入
    void traversal_preOrder(TreeNode* cur, bool &result) {
        // 2、终止条件
        if (cur == NULL) return;
        if (cur->left && cur->left->val >= cur->val) result = 0;
        if (cur->right && cur->right->val <= cur->val) result = 0;

        // 3、单层递归逻辑
        if (result) traversal_preOrder(cur->left, result);     // 左
        if (result) traversal_preOrder(cur->right, result);    // 右
    }
    bool isValidBST(TreeNode* root) {
        bool result = 1;
        traversal_preOrder(root, result);
        return result;
    }
};

  在leetcode执行时遇到下面的错误,再次读题,发现是所有左子树的键值小于中间节点键值,所有右子树键值大于中间节点键值,这个性质和中序遍历有所关联。如此一来,我们就想到用中序遍历来做,中序遍历数组是一个有序数组,判断该数组是否有序即可
在这里插入图片描述

  程序如下

class Solution {
public:
    void traversal_midOrder(TreeNode* cur, vector<int>& vec) {
        if (cur == NULL) return;
        traversal_midOrder(cur->left, vec);     // 左
        vec.push_back(cur->val);                // 中
        traversal_midOrder(cur->right, vec);    // 右
    }

    bool isValidBST(TreeNode* root) {
        if (root == NULL) return {};
        vector<int> v;
        traversal_midOrder(root, v);
        for (int i = 0; i < v.size()-1; i++) {
            if (v[i] >= v[i + 1]) return false;
        }
        return true;
    }
};

三、完整代码

# include <iostream>
# include <vector>
# include <string>
# include <queue>
using namespace std;

// 树节点定义
struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode() : val(0), left(nullptr), right(nullptr) {}
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
    TreeNode(int x, TreeNode* left, TreeNode* right) : val(x), left(left), right(right) {}
};

class Solution {
public:
    void traversal_midOrder(TreeNode* cur, vector<int>& vec) {
        if (cur == NULL) return;
        traversal_midOrder(cur->left, vec);     // 左
        vec.push_back(cur->val);                // 中
        traversal_midOrder(cur->right, vec);    // 右
    }

    bool isValidBST(TreeNode* root) {
        if (root == NULL) return {};
        vector<int> v;
        traversal_midOrder(root, v);
        for (int i = 0; i < v.size()-1; i++) {
            if (v[i] >= v[i + 1]) return false;
        }
        return true;
    }
};

class Solution2 {
public:
    // 1、输入参数, 返回值为result,以引用方式传入
    void traversal_preOrder(TreeNode* cur, bool &result) {
        // 2、终止条件
        if (cur == NULL) return;
        if (cur->left && cur->left->val >= cur->val) result = 0;
        if (cur->right && cur->right->val <= cur->val) result = 0;

        // 3、单层递归逻辑
        if (result) traversal_preOrder(cur->left, result);     // 左
        if (result) traversal_preOrder(cur->right, result);    // 右
    }
    bool isValidBST(TreeNode* root) {
        bool result = 1;
        traversal_preOrder(root, result);
        return result;
    }
};

// 前序遍历迭代法创建二叉树,每次迭代将容器首元素弹出(弹出代码还可以再优化)
void Tree_Generator(vector<string>& t, TreeNode*& node) {
    if (!t.size() || t[0] == "NULL") return;    // 退出条件
    else {
        node = new TreeNode(stoi(t[0].c_str()));    // 中
        if (t.size()) {
            t.assign(t.begin() + 1, t.end());
            Tree_Generator(t, node->left);              // 左
        }
        if (t.size()) {
            t.assign(t.begin() + 1, t.end());
            Tree_Generator(t, node->right);             // 右
        }
    }
}

template<typename T>
void my_print(T& v, const string msg)
{
    cout << msg << endl;
    for (class T::iterator it = v.begin(); it != v.end(); it++) {
        cout << *it << ' ';
    }
    cout << endl;
}

template<class T1, class T2>
void my_print2(T1& v, const string str) {
    cout << str << endl;
    for (class T1::iterator vit = v.begin(); vit < v.end(); ++vit) {
        for (class T2::iterator it = (*vit).begin(); it < (*vit).end(); ++it) {
            cout << *it << ' ';
        }
        cout << endl;
    }
}

// 层序遍历
vector<vector<int>> levelOrder(TreeNode* root) {
    queue<TreeNode*> que;
    if (root != NULL) que.push(root);
    vector<vector<int>> result;
    while (!que.empty()) {
        int size = que.size();  // size必须固定, que.size()是不断变化的
        vector<int> vec;
        for (int i = 0; i < size; ++i) {
            TreeNode* node = que.front();
            que.pop();
            vec.push_back(node->val);
            if (node->left) que.push(node->left);
            if (node->right) que.push(node->right);
        }
        result.push_back(vec);
    }
    return result;
}

int main()
{
    vector<string> t = { "5", "4", "NULL", "NULL", "6", "3", "NULL", "NULL", "7", "NULL", "NULL" };   // 前序遍历
    my_print(t, "目标树");
    TreeNode* root = new TreeNode();
    Tree_Generator(t, root);
    vector<vector<int>> tree = levelOrder(root);
    my_print2<vector<vector<int>>, vector<int>>(tree, "目标树:");

    Solution s;
    bool result = s.isValidBST(root);
    if (result) cout << "是一棵二叉搜索树" << endl;
    else cout << "不是一棵二叉搜索树" << endl;

	system("pause");
	return 0;
}

end

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

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

相关文章

微信小程序支付

当下&#xff0c;微信小程序十分火爆&#xff0c;现在无论是购物还是生活服务&#xff0c;都是推荐你使用微信小程序&#xff0c;主要是它无需下载安装就可以使用&#xff0c;让手机变得非常清爽&#xff0c;给用户也带来很大的方便之处。 今天给大家分享的是&#xff0c;微信…

win10 任务栏预览设置为列表效果

背景 在win10系统&#xff0c;当同一个应用&#xff08;如文件资源管理器&#xff0c;git bash&#xff0c;word等&#xff09;打开多个页面时&#xff0c;当个数少于17&#xff08;大约&#xff09;个时&#xff0c;其默认预览效果为平铺&#xff0c;在大于17个时&#xff0c…

【Android知识笔记】UI体系(四)

事件分发原理 屏幕事件会由Linux通过JNI传给WMS(WindowManagerService),然后由WMS传给Activity,最终经过PhoneWindow->DecorView开始往下分发。 View的事件分发 View的事件分发核心源码为 dispatchTouchEvent() 方法: public boolean dispatchTouchEvent(MotionEvent …

如何制作非对称型加密

非对称加密是一种常见的加密方式&#xff0c;它使用一对密钥&#xff1a;公钥和私钥。下面是一种制作非对称加密的基本步骤&#xff1a; 首先&#xff0c;生成一对公钥和私钥。公钥是用于加密的&#xff0c;可以公开给其他人使用&#xff0c;而私钥是用于解密的&#xff0c;需要…

1-centOS7搭建伪分布式

前言&#xff1a;虚拟机快照的使用 VMware Workstation 软件可以用快照进行迅速的虚拟机状态的切换 ※. 类似于虚拟机备份&#xff0c; 可以使用备份进行快速恢复。 比如没安装jdk之前拍摄快照来备份 ※. 若jdk没安装好或者jdk环境变量配置的有问题&#xff0c; 可以用安装之…

【C语言基础】那些你可能不知道的C语言“潜规则”

&#x1f4e2;&#xff1a;如果你也对机器人、人工智能感兴趣&#xff0c;看来我们志同道合✨ &#x1f4e2;&#xff1a;不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 &#x1f4e2;&#xff1a;文章若有幸对你有帮助&#xff0c;可点赞 &#x1f44d;…

公务员和事业单位的差别有多大?

公务员和事业单位是两种不同的就业形式和组织类型&#xff0c;它们在以下几个方面存在一些差别&#xff1a; 1. 归属关系&#xff1a;公务员属于政府部门的编制人员&#xff0c;直接依附于政府机构。而事业单位是独立法人实体&#xff0c;独立承担法人责任&#xff0c;不隶属于…

2023年-暑期旅行的复盘(0701~0820)

目录 一、旅行城市及线路图&#xff08;22&#xff09;二、3个战略目标三、旅行 3 原则四、数据统计五、总结附录1-消费明细-南方&#xff08;0701~0725&#xff09;7月1日----深圳7月2日----香港7月3日----深圳7月4日----佛山7月5日----澳门7月6日----深圳7月7日----福州7月8日…

趣链BaaS服务平台调研

目录 一、菜单功能二、其他说明2.1、服务平台的部署方式2.2、链本身2.3、核心使用流程 趣链hyperchain管理平台文档地址&#xff1a;https://docs.hyperchain.cn/document/overview?type1 一、菜单功能 菜单子菜单/功能点子菜单/功能点功能描述控制台平台概览主要用于展示当…

【vue2第十六章】VueRouter 声明式导航(跳转传参)、路由重定向、页面未找到的提示页面404、vue路由模式设置

声明式导航(跳转传参) 在一些特定的需求中&#xff0c;跳转路径时我们是需要携带参数跳转的&#xff0c;比如有一个搜索框&#xff0c;点击搜索的按钮需要跳转到另外一个页面组件&#xff0c;此时需要把用户输入的input框的值也携带到那页面进行发送请求&#xff0c;请求数据。…

golang validator 包的使用指北

看到 validator 咱们第一反应会想起啥&#xff1f;见名知意我就可以知道他是一个验证器&#xff0c;如果用过 gin web 框架的同学&#xff0c;自然是用过 gin 里面的 validator&#xff0c;只不过 gin 中使用的关键字是 binding 去做标识 开门见山 Validator 实际上是一个验证…

为什么要使用设计模式,以及使用设计模式的好处

在软件开发中&#xff0c;衡量软件质量只要包含如下指标&#xff1a; 正确性可维护性可读性可扩展性简洁性可测试性健壮性灵活性可复用性 然而&#xff0c;对于一些刚入行的新程序员来说&#xff0c;往往会注意不到上面这些问题&#xff0c;从而产生了一些让人头皮发麻的烂代…

用python实现基本数据结构【04/4】

说明 如果需要用到这些知识却没有掌握&#xff0c;则会让人感到沮丧&#xff0c;也可能导致面试被拒。无论是花几天时间“突击”&#xff0c;还是利用零碎的时间持续学习&#xff0c;在数据结构上下点功夫都是值得的。那么Python 中有哪些数据结构呢&#xff1f;列表、字典、集…

5分钟 将“.py”文件转为“.pyd”文件

代码&#xff1a; from distutils.core import setup from distutils.extension import Extension from Cython.Build import cythonize import osfile_list os.listdir("./") extensions [] for file in file_list:if file.endswith(".py") and file !…

软件界面常见的布局窗口基本布局和名字

软件基本界面分布 下图是PS界面的各个功能块布局&#xff0c;&#xff08;图片来源网络&#xff09; 基本界面功能 常见的界面中&#xff0c;菜单栏和工具栏一般都是挨着的&#xff0c;属性窗口在右边&#xff0c;例如excel 程序编程软件界面中 一般比普通的软件多出来工…

linux-OpenSSL升级

1.安装编译所需的安装包 yum install -y gcc make perl zlib-devel 2.从 OpenSSL 官网下载&#xff08;https://www.openssl.org/source/openssl-1.1.1v.tar.gz&#xff09; 注:如果原先版本为1.x.x,升级时还是需要选择1.x.x 3. 编译安装 # 解压tar -xvf openssl-1.1.1v.tar…

flyway7.1.1适配人大金仓postgres版本

1、进入flyway github仓库下载flyway7.1.1版本源码&#xff0c;搜索7.1.1&#xff0c;下载地址为&#xff1a;https://github.com/flyway/flyway/releases 2、解压源码&#xff0c; 新建目录kingbase&#xff0c;将postgres目录文件拷贝进kingbase&#xff0c;修改下文件名&…

OpenCV(三十三):计算轮廓面积与轮廓长度

1.介绍轮廓面积与轮廓长度 轮廓面积&#xff08;Contour Area&#xff09;是指轮廓所包围的区域的总面积。通常情况下&#xff0c;轮廓面积的单位是像素的平方。 轮廓长度&#xff08;Contour Length&#xff09;又称周长&#xff08;Perimeter&#xff09;&#xff0c;表示轮廓…

华为云云耀云服务器L实例评测|在Linux下部署Etherpad文档编辑器

华为云云耀云服务器L实例评测&#xff5c;在Linux下部署Etherpad文档编辑器 一、前言1.1 云耀云服务器L实例简介1.2 Etherpad简介 二、本次实践介绍2.1 本次实践简介2.2 本次环境规划 三、购买云耀云服务器L实例3.1 购买云耀云服务器L实例3.3 查看云耀云服务器L实例状态3.4 重置…

Pytorch3D多角度渲染.obj模型

3D理解在从自动驾驶汽车和自主机器人到虚拟现实和增强现实的众多应用中发挥着至关重要的作用。在过去的一年里&#xff0c;PyTorch3D已经成为一个越来越流行的开源框架&#xff0c;用于使用Python进行3D深度学习。值得庆幸的是&#xff0c;PyTorch3D 库背后的人员已经完成了实现…