首页 > 其他分享 >day39_0098.验证二叉搜索树

day39_0098.验证二叉搜索树

时间:2022-12-22 20:46:35浏览次数:39  
标签:遍历 return cur day39 二叉 0098 NULL root left

0098.验证二叉搜索树

class Solution {
public:
    bool isValidBST(TreeNode* root) {
        if (root == NULL)   return false;
        if (root->left) {
            if (root->left->val > root->val)
                return false;
            else
                return isValidBST(root->left);
        }
        if (root->right) {
            if (root->right->val < root->val)
                return false;
            else
                return isValidBST(root->right);
        }
        return true;
    }
};
  • 以上是我的迭代法 有问题
  • 下面总结卡哥的几种代码
    • 递归法1----借助数组比较大小
    • 递归法2-----初始化最小值为LONG_MIN
    • 递归法3----直接将整棵树最左边的叶子节点设为最小值
    • 迭代法
  • 递归法1
class Solution {
private:
    vector<int> vec;
    void traversal(TreeNode* root) {
        if (root == NULL) return;
        traversal(root->left);
        vec.push_back(root->val); 
        traversal(root->right);
    }
public:
    bool isValidBST(TreeNode* root) {
        vec.clear(); 
        traversal(root);
        for (int i = 1; i < vec.size(); i++) {
            if (vec[i] <= vec[i - 1]) return false;
        }
        return true;
    }
};
  • 思路解析

    • 把数组定义和traversal函数放在private里

    • root == NULL 返回真而不是假

      • 理由是 可以使用反证法 如果此时结点为NULL 那么你希望返回假结束所有遍历吗 当然不能 只有元素大小关系不符合左小于中小于右的时候 才需要return false

      • 关于空值有必要再次强调 假设root == NULL 可以把空值当作参数进行传递如traversal(root); 但不能对空值进行任何操作如(root->left);

    • 关于遍历函数

      • 采用什么遍历方式取决于遍历的目的: 把所有节点元素值按照左中右的顺序存入数组vec中 以便在主函数中通过判断数组是否为有序递增来验证遍历得到的树是否为二叉搜索树 因此遍历函数traversal采用中序遍历
      • 遍历的写法: 中序遍历:遍历左----对当前节点(中间节点)的操作--------遍历右
    • 关于主函数

      • 注意二叉搜索树 元素值相等也是不被允许的一种情况
  • 递归法2-----初始化最小值为LONG_MIN

class Solution {
public:
    long long maxVal = LONG_MIN;
    bool isValidBST(TreeNode* root) {
        if (root == NULL)   return true;

        bool left = isValidBST(root->left);  // 左
        if (maxVal < root->val)  // 中
            maxVal = root->val;
        else
            return false;
        bool right = isValidBST(root->right);  //  右

        return left && right;
    }
};
  • 思路解析

    • maxVa之所以选择longlong类型最小值 是因为后台数据有int最小值测试用例

    • 如果测试数据中有 longlong的最小值, 不可能在初始化一个更小的值 建议避免 初始化最小值,如下代码方法取到最左面节点的数值来比较。

  • 递归法3----直接将整棵树最左边的叶子节点设为最小值

class Solution {
public:
    TreeNode* pre = NULL;
    bool isValidBST(TreeNode* root) {
        if (root == NULL)  return true;

        bool left = isValidBST(root->left);
        if (pre != NULL && pre->val >= root->val)
            return false;
        pre = root;
        bool right = isValidBST(root->right);

        return left && right;
    }
};
  • 思路解析

    • 既然不单独再写一个遍历函数而是直接在所给的主函数里面进行遍历 那么必然有些元素需要额外定义在主函数外 如这段代码的pre和上一段代码的maxVal变量
    • 这段代码逻辑是 在中序遍历的框架下 先获取到整棵树最左边元素值
  • 迭代法

class Solution {
public:
    bool isValidBST(TreeNode* root) {
        stack<TreeNode*> st;
        TreeNode* cur = root;
        TreeNode* pre = NULL; // 记录前一个节点
        while (cur != NULL || !st.empty()) {
            if (cur != NULL) {
                st.push(cur);
                cur = cur->left;                // 左
            } else {
                cur = st.top();                 // 中
                st.pop();
                if (pre != NULL && cur->val <= pre->val)
                return false;
                pre = cur; //保存前一个访问的结点

                cur = cur->right;               // 右
            }
        }
        return true;
    }
};
  • 下次看

标签:遍历,return,cur,day39,二叉,0098,NULL,root,left
From: https://www.cnblogs.com/deservee/p/16999533.html

相关文章

  • 二叉树神级遍历!(Morris)
      我们之前说了二叉树基础及二叉的几种遍历方式及练习题本文大纲前序遍历前序遍历的顺序是,对于树中的某节点,先遍历该节点,然后再遍历其左子树,最后遍历其右子树......
  • 学过,以前做过,所以顺带也做了迭代方法遍历二叉树
    前序遍历/***<ahref="https://leetcode.cn/problems/binary-tree-preorder-traversal/">144.二叉树的前序遍历</>*<p>*中左右*/publ......
  • 【算法实践】他山之石,可以攻玉--利用完全二叉树快速实现堆排序
    前言什么是堆堆是一种数据结构,它是完全二叉树或者是近似完全二叉树的一种数据结构,树中每个结点的值都不小于(或不大于)其左右孩子结点的值。何为完全二叉树完全二叉树是一种......
  • 求二叉树的深度
    求二叉树的深度TimeLimit:1000MSMemorylimit:65536K题目描述已知一颗二叉树的中序遍历序列和后序遍历序列,求二叉树的深度。输入T组数据。每组数据包括两个长......
  • 数据结构实验之求二叉树后序遍历和层次遍历
    数据结构实验之求二叉树后序遍历和层次遍历TimeLimit:1000MSMemorylimit:65536K题目描述 已知一棵二叉树的前序遍历和中序遍历,求二叉树的后序遍历。输入......
  • 力扣-538-把二叉搜索树转换为累加树
    intpreSum=0; voidtraversal(TreeNode*root){ if(!root)return; traversal(root->right); root->val+=preSum; preSum=root->val; traversal(roo......
  • 数据结构-二叉树遍历非递归
    前序遍历voidpreorder(BTNODEBT){BTNODESTACK[100];inttop=-1;STACK[++top]=BT;BTNODEp=null;while(top!=-1){BTNO......
  • 二叉树的最大/最小深度
    1.深度与高度二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始)二叉树节点的高度:指从该节点到叶子节点的最长简单路径......
  • LeetCode 102_二叉树的层序遍历
    LeetCode102:二叉树的层序遍历题目给你二叉树的根节点root,返回其节点值的层序遍历。(即逐层地,从左到右访问所有节点)。示例1:输入:root=[3,9,20,null,null,15,7]......
  • 剑指offer 二叉树的深度(C++)
    题目描述输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。代码实现/*structTreeNode{intval;......