算法训练day22 LeetCode235

发布时间 2023-09-27 16:43:27作者: 烫烫烫汤圆

算法训练day22 LeetCode235.701.450.

235. 二叉搜索树的最近公共祖先

题目

235. 二叉搜索树的最近公共祖先 - 力扣(LeetCode)

题解

代码随想录 (programmercarl.com)

  • 对于二叉树,可以用递归回溯的方式

  • 对于二叉搜索树,由其根节点大于左右子树中结点,所以当第一次遍历到根节点值在[p,q]之间时,此节点为最近公告祖先

  • 递归遍历单支

    • class Solution
      {
      public:
          TreeNode *lowestCommonAncestor(TreeNode *root, TreeNode *p, TreeNode *q)
          {
              {
                  if (root->val > p->val && root->val > q->val)
                  {
                      return lowestCommonAncestor(root->left, p, q);
                  }
                  else if (root->val < p->val && root->val < q->val)
                  {
                      return lowestCommonAncestor(root->right, p, q);
                  }
                  else
                      return root;
              }
          }
      };
      
  • 迭代遍历

    • class Solution
      {
      public:
          TreeNode *lowestCommonAncestor(TreeNode *root, TreeNode *p, TreeNode *q)
          {
              while (root)
              {
                  if (root->val > p->val && root->val > q->val)
                      root = root->left;
                  else if (root->val < p->val && root->val < q->val)
                      root = root->right;
                  else
                      return root;
              }
              return NULL;
          }
      };
      

701.二叉搜索树中的插入操作

题目

701. 二叉搜索树中的插入操作 - 力扣(LeetCode)

题解

代码随想录 (programmercarl.com)

  • 根据二叉平衡树特点遍历,找到空节点插入即可(函数有返回值)

  • class Solution
    {
    public:
        TreeNode *insertIntoBST(TreeNode *root, int val)
        {
            if (root == NULL)
            {
                TreeNode *node = new TreeNode(val);
                return node;
            }
            if (root->val > val)
                root->left = insertIntoBST(root->left, val);
            if (root->val < val)
                root->right = insertIntoBST(root->right, val);
            return root;
        }
    };
    
  • 递归遍历(函数无返回值)

  • class Solution
    {
    private:
        TreeNode *parent;
        void traversal(TreeNode *cur, int val)
        {
            if (cur == NULL)
            {
                TreeNode *node = new TreeNode(val);
                if (val > parent->val)
                    parent->right = node;
                else
                    parent->left = node;
                return;
            }
            parent = cur;
            if (val > cur->val)
                traversal(cur->right, val);
            if (val < cur->val)
                traversal(cur->left, val);
        }
    
    public:
        TreeNode *insertIntoBST(TreeNode *root, int val)
        {
            parent = new TreeNode(0);
            if (root == NULL)
            {
                root = new TreeNode(val);
            }
            traversal(root, val);
            return root;
        }
    };
    

450.删除二叉搜索树中的节点

题目

450. 删除二叉搜索树中的节点 - 力扣(LeetCode)

题解

代码随想录 (programmercarl.com)

  • 递归

    • 函数的参数是根节点值和目标值,返回值是子节点指针

    • 中止条件:

      • 节点为空-->没有找到目标 直接返回检查的节点指针即可
      • 节点值等于目标值
        • 节点为叶子节点,直接删除,返回空
        • 只有左子节点,返回左子节点
        • 只有右子节点,返回右子节点
        • 左右均有,将左子节点连接在右子节点最深左子节点之后,删除左子节点,返回右子节点
    • 单层逻辑:目标值大于节点值则遍历右子树,并用右子树承接深一层递归的返回值

    • class Solution
      {
      public:
          TreeNode *deleteNode(TreeNode *root, int key)
          {
              if (root == NULL)
                  return root;
              if (root->val == key)
              {
                  if (root->left == NULL)
                      return root->right;
                  else if (root->right == NULL)
                      return root->left;
                  else
                  {
                      TreeNode *cur = root->right;
                      while (cur->left != NULL) // 找到要删除节点的最底层左节点
                      {
                          cur = cur->left;
                      }
                      cur->left = root->left;
                      TreeNode *tmp = root;	//标记待删除节点,准备删除
                      root = root->right;
                      delete tmp;
                      return root;
                  }
              }
              if (root->val > key)
                  root->left = deleteNode(root->left, key);
              if (root->val < key)
                  root->right = deleteNode(root->right, key);
              return root;
          }
      };