PigyChan_LeetCode 面试题 04.05. 合法二叉搜索树

面试题 04.05. 合法二叉搜索树

难度中等

实现一个函数,检查一棵二叉树是否为二叉搜索树。
示例 1:
在这里插入图片描述

示例 2:
在这里插入图片描述

思路1.0:

遍历树,查看每个节点是不是都符合“左子树小,右子树大”的条件。
判断是否是搜索二叉树节点的几种情况:
1)左子树节点值小于当前节点值,右子树节点值大于当前节点值
2)只存在左子树,且其节点值小于当前节点值
2)只存在右子树,且其节点值大于当前节点值
3)没有子树

代码1.0:
  class Solution {
  public:
      bool isMatching(TreeNode* TNode)
      {
          if (TNode->left != NULL && TNode->right != NULL)
          {
              if (TNode->left->val < TNode->val && TNode->right->val > TNode->val)
                  return true;
          }
          else if (TNode->left != NULL)
          {
              if (TNode->left->val < TNode->val)
                  return true;
          }
          else if (TNode->right != NULL)
          {
              if (TNode->right->val > TNode->val)
                  return true;
          }
          else if (TNode->left == NULL && TNode->right == NULL)
          {
              return true;
          }
          return false;
      }


      bool isValidBST(TreeNode* root) {
          if (root == NULL) return true;
          return isMatching(root) && isValidBST(root->left) && isValidBST(root->right);
      }
  };

出错了,只考虑了每个节点和左右子树的关系,没考虑到根节点的,所有左子树都比根节点值要小,所有右子树都比根节点值要大。

思路2.0:由此可得判断每个节点需要其左右子树的所有信息,所以使用后序遍历,因为根节点的左右子树判断标准不同,所以从根节点的左右子树两处开始后序遍历
代码2.0:
  class Solution {
  public:
      void PosOrderLeft(TreeNode* TNode,bool& rst)
      {
          if (TNode != NULL)
          {
              PosOrderLeft(TNode->left,rst);
              PosOrderLeft(TNode->right,rst);
              if (TNode->left != NULL && TNode->right != NULL)
              {
                  if (TNode->left->val >= TNode->val || TNode->right->val <= TNode->val)
                      rst = false;
                  TNode->val = TNode->right->val;
              }
              else if (TNode->left != NULL)
              {
                  if (TNode->left->val >= TNode->val)
                      rst = false;
              }
              else if (TNode->right != NULL)
              {
                  if (TNode->right->val <= TNode->val)
                      rst = false;
                  TNode->val = TNode->right->val;
              }
          }
      }


      void PosOrderRight(TreeNode* TNode, bool& rst)
      {
          if (TNode != NULL)
          {
              PosOrderRight(TNode->left, rst);
              PosOrderRight(TNode->right, rst);
              if (TNode->left != NULL && TNode->right != NULL)
              {
                  if (TNode->left->val >= TNode->val || TNode->right->val <= TNode->val)
                      rst = false;
                  TNode->val = TNode->left->val;
              }
              else if (TNode->left != NULL)
              {
                  if (TNode->left->val >= TNode->val)
                      rst = false;
                  TNode->val = TNode->left->val;
              }
              else if (TNode->right != NULL)
              {
                  if (TNode->right->val <= TNode->val)
                      rst = false;
              }
          }
      }


      bool isValidBST(TreeNode* root) {
          if (root == NULL) return true;
          bool rstLeft = true, rstRight = true, rstFinal = true;
          PosOrderLeft(root->left, rstLeft);
          PosOrderRight(root->right, rstRight);


          if (root->left != NULL && root->right != NULL)
          {
              if (root->left->val >= root->val || root->right->val <= root->val)
                  rstFinal = false;
          }
          else if (root->left != NULL)
          {
              if (root->left->val >= root->val)
                  rstFinal = false;
          }
          else if (root->right != NULL)
          {
              if (root->right->val <= root->val)
                  rstFinal = false;
          }


          return rstLeft && rstRight && rstFinal;


      }
  };

又臭又长的代码,还尼玛出错了!

思路3.0(已看题解):

题解里是在遍历每个节点时,一直维护着这个节点的取值范围,左右子树的范围变化不同
1)左子树:min=min,max=TNode->val
2)右子树:min=TNode->val,max=max
感觉自己在“一颗节点和它的左右子树”这一结构吊得太死了,如果反过来思考”一个子节点(左或右)与他的父节点“,就可能想到题解里大佬们的思路了。

代码3.0(已完成):
  class Solution {
  public:
      bool isMatching(TreeNode* TNode, long min, long max)
      {
          if (TNode == NULL) return true;
          if (TNode->val >= max || TNode->val <= min) return false;


          bool leftCd = isMatching(TNode->left, min, TNode->val);
          bool rightCd = isMatching(TNode->right, TNode->val, max);


          return leftCd && rightCd;
      }


      bool isValidBST(TreeNode* root) {
          if (root == NULL) return true;
          return isMatching(root->left, LONG_MIN, root->val) && isMatching(root->right, root->val, LONG_MAX);


      }
  };

代码感觉想是做类匹配二叉树时用的,难道这就是大佬口中的双百算法嘛

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值