二叉樹問題(一)-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