二叉树问题(一)-LeetCode 110、617、101、814、655、98、654(递归思路)

  • 2019 年 12 月 24 日
  • 笔记

作者:TeddyZhang,公众号:算法工程师之路

二叉树问题(一):

LeetCode # 110 617 101 814 655 98 654

1

编程题

【LeetCode #110】平衡二叉树

给定一个二叉树,判断它是否是高度平衡的二叉树。 本题中,一棵高度平衡二叉树定义为: 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1

解题思路:自上而下递归得到每个子树的高度,依据定义即可。

/**   * Definition for a binary tree node.   * struct TreeNode {   *     int val;   *     TreeNode *left;   *     TreeNode *right;   *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}   * };   */  class Solution {  public:      int height(TreeNode* node) {          if (node == nullptr) return ;          return max(height(node->left), height(node->right)) + ;      }      bool isBalanced(TreeNode* root) {          if (root == nullptr) return true;          int left = height(root->left);          int right = height(root->right);          return abs(left-right) <=  && isBalanced(root->left) && isBalanced(root->right);      }  };  

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/balanced-binary-tree/

【LeetCode #617】合并二叉树

给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。 你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。

/**   * Definition for a binary tree node.   * struct TreeNode {   *     int val;   *     TreeNode *left;   *     TreeNode *right;   *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}   * };   */  class Solution {  public:      TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {          if (t1 == nullptr) return t2;          if (t2 == nullptr) return t1;          if (t1 && t2) {              t1->val += t2->val;              t1->left = mergeTrees(t1->left, t2->left);              t1->right = mergeTrees(t1->right, t2->right);              return t1;          }else return nullptr;      }  };  

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/merge-two-binary-trees

【LeetCode #101】对称二叉树

给定一个二叉树,检查它是否是镜像对称的。

例如,二叉树 [1,2,2,3,4,4,3] 是对称的。

1 / 2 2 / / 3 4 4 3

class Solution {  public:      bool dfs(TreeNode* left, TreeNode* right) {          if (left == nullptr && right == nullptr)              return true;          if (!left || !right)              return false;          if (left->val != right->val){              return false;          } else {              return dfs(left->left, right->right) && dfs(left->right, right->left);          }      }      bool isSymmetric(TreeNode* root) {          return dfs(root, root);      }  };  

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/symmetric-tree

【LeetCode #814】二叉树剪枝

给定二叉树根结点 root ,此外树的每个结点的值要么是 0,要么是 1。

返回移除了所有不包含 1 的子树的原二叉树。

( 节点 X 的子树为 X 本身,以及所有 X 的后代。)

示例1: 输入: [1,null,0,0,1] 输出: [1,null,0,null,1]

解题思路:

遍历的查找每个节点,然后判断该二叉树的某个子树中是否存在节点值为1的数字,如果存在,则对应子树的根节点置为nullptr,否则就不变化。

class Solution {  public:      bool containOne(TreeNode* root) {          if (root == nullptr) return false;          bool ll = containOne(root->left);          bool rr = containOne(root->right);          if (!ll) {              root->left = nullptr;          }          if (!rr) {              root->right = nullptr;          }          return ll || rr || root->val == ;      }        TreeNode* pruneTree(TreeNode* root) {          containOne(root);          return root;      }  };  

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/binary-tree-pruning

【LeetCode #655】输出二叉树

在一个 m*n 的二维字符串数组中输出二叉树,并遵守以下规则:

行数 m 应当等于给定二叉树的高度。 列数 n 应当总是奇数。 根节点的值(以字符串格式给出)应当放在可放置的第一行正中间。根节点所在的行与列会将剩余空间划分为两部分(左下部分和右下部分)。你应该将左子树输出在左下部分,右子树输出在右下部分。左下和右下部分应当有相同的大小。即使一个子树为空而另一个非空,你不需要为空的子树输出任何东西,但仍需要为另一个子树留出足够的空间。然而,如果两个子树都为空则不需要为它们留出任何空间。 每个未使用的空间应包含一个空的字符串""。 使用相同的规则输出子树。

示例 1: 输入: 1 / 2 输出: [["", "1", ""], ["2", "", ""]]

解题思路:

首先求出二叉树的高度m,进而得到n = pow(1, m)-1; 然后我们二分的进行输出到二维vector中,使用二分法。

/**   * Definition for a binary tree node.   * struct TreeNode {   *     int val;   *     TreeNode *left;   *     TreeNode *right;   *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}   * };   */  class Solution {  public:      vector<vector<string>> printTree(TreeNode* root) {          int m = getHeight(root);          int n = pow(, m) - ;          vector<vector<string>> res(m, vector<string>(n, ""));          dfsPrint(root, res, , , n-1);          return res;      }    private:      int getHeight(TreeNode* node) {          if (node == nullptr) return ;          return max(getHeight(node->left), getHeight(node->right)) + ;      }        void dfsPrint(TreeNode* root, vector<vector<string>>& res, int row, int start, int end) {          if(!root || (start > end)) return;          int mid = start + (end - start) / ;          res[row][mid] = to_string(root->val);          dfsPrint(root->left, res, row+, start, mid);          dfsPrint(root->right, res, row+, mid+, end);      }  };  

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/print-binary-tree

【LeetCode #98】验证二叉搜索树

给定一个二叉树,判断其是否是一个有效的二叉搜索树。 假设一个二叉搜索树具有如下特征:

  • 节点的左子树只包含小于当前节点的数。
  • 节点的右子树只包含大于当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。

示例 1: 输入: 2 / 1 3 输出: true

解题思路:

复习中序遍历,对二叉树进行中序遍历,并使用pre节点储存当前节点的上一节点,然后保证边界结果为递增序列即可!

/**   * Definition for a binary tree node.   * struct TreeNode {   *     int val;   *     TreeNode *left;   *     TreeNode *right;   *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}   * };   */  class Solution {  public:      bool isValidBST(TreeNode* root) {          stack<TreeNode*> sta;          TreeNode* pre = nullptr;          TreeNode* cur = root;          while(cur != nullptr || !sta.empty()) {              if (cur != nullptr) {                  sta.push(cur);                  cur = cur->left;              }else {                  cur = sta.top();                  sta.pop();                  if (pre && (pre->val >= cur->val)) {                      return false;                  }                  pre = cur;                  cur = cur->right;              }          }          return true;      }  };  

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/validate-binary-search-tree

【LeetCode #654】最大二叉树

给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下:

二叉树的根是数组中的最大元素。

  • 左子树是通过数组中最大值左边部分构造出的最大二叉树。
  • 右子树是通过数组中最大值右边部分构造出的最大二叉树。
  • 通过给定的数组构建最大二叉树,并且输出这个树的根节点。

解题思路:

首先找到最大值,然后构建结点,从最大值位置分成两个区间,然后分别使用相应的区间构造root的左右子树,递归构造即可!

/**   * Definition for a binary tree node.   * struct TreeNode {   *     int val;   *     TreeNode *left;   *     TreeNode *right;   *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}   * };   */  class Solution {  public:      TreeNode* constructMaximumBinaryTree(vector<int>& nums) {          if(nums.size() == ) return nullptr;          auto it = max_element(nums.begin(), nums.end());          TreeNode* root = new TreeNode(*it);          vector<int> ll(nums.begin(), it);          vector<int> rr(it+, nums.end());          root->left = constructMaximumBinaryTree(ll);          root->right = constructMaximumBinaryTree(rr);          return root;      }  };  

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/maximum-binary-tree