二叉樹問題(二)-LeetCode 965、563、993、958、919(樹深度,層次遍歷)
- 2019 年 12 月 24 日
- 筆記
作者:TeddyZhang,公眾號:算法工程師之路
二叉樹問題(二):
LeetCode # 965 563 993 958 919
1
編程題
【LeetCode #965】單值二叉樹
如果二叉樹每個節點都具有相同的值,那麼該二叉樹就是單值二叉樹。 只有給定的樹是單值二叉樹時,才返回 true;否則返回 false。
(迭代法,中序遍歷)
class Solution { public: bool isUnivalTree(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; } };
(遞歸法)
class Solution { public: bool isUnivalTree(TreeNode* root) { if (root == nullptr) return true; if (root->left && root->left->val != root->val) { return false; } if (root->right && root->right->val != root->val) { return false; } return isUnivalTree(root->left) && isUnivalTree(root->right); } };
來源:力扣(LeetCode) 鏈接:https://leetcode-cn.com/problems/univalued-binary-tree/
【LeetCode #563】二叉樹的坡度
給定一個二叉樹,計算整個樹的坡度。
一個樹的節點的坡度定義即為,該節點左子樹的結點之和和右子樹結點之和的差的絕對值。空結點的的坡度是0。 整個樹的坡度就是其所有節點的坡度之和。
示例: 輸入: 1 / 2 3 輸出: 1 解釋: 結點的坡度 2 : 0 結點的坡度 3 : 0 結點的坡度 1 : |2-3| = 1 樹的坡度 : 0 + 0 + 1 = 1
解題思路:
首先我們寫出一個計算一個二叉樹中子樹的節點和的遞歸式子,然後再遞歸參數中使用count來累加兩個子樹節點和的差值,最後返回count即可。注意使用引用傳遞而不是值傳遞。
/** * 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 add(TreeNode* node, int& count) { if(node == nullptr) return ; int left = add(node->left, count); int right = add(node->right, count); count += abs(left - right); return left+right+node->val; } int findTilt(TreeNode* root) { int res = ; add(root, res); return res; } };
來源:力扣(LeetCode) 鏈接:https://leetcode-cn.com/problems/binary-tree-tilt
【LeetCode #993】二叉樹的堂兄節點
在二叉樹中,根節點位於深度 0 處,每個深度為 k 的節點的子節點位於深度 k+1 處。 如果二叉樹的兩個節點深度相同,但父節點不同,則它們是一對堂兄弟節點。 我們給出了具有唯一值的二叉樹的根節點 root,以及樹中兩個不同節點的值 x 和 y。 只有與值 x 和 y 對應的節點是堂兄弟節點時,才返回 true。否則,返回 false
解題思路:
使用pair類型儲存對應x節點以及y節點的深度和父節點的值,然後進行比較即可。 注意該二叉樹中的值都是唯一的,沒有重複的。
/** * 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: void find(TreeNode* node, int val, int dep, int par, pair<int, int>& res) { if (node == nullptr) return; if (node->val == val) { res.first = dep; res.second = par; return; } else { find(node->left, val, dep+, node->val, res); find(node->right, val, dep+, node->val, res); } } bool isCousins(TreeNode* root, int x, int y) { pair<int, int> res1, res2; find(root, x, , -1, res1); // 根節點的父節點值設為-1 find(root, y, , -1, res2); return (res1.first == res2.first) && (res1.second != res2.second); } };
來源:力扣(LeetCode) 鏈接:https://leetcode-cn.com/problems/cousins-in-binary-tree
【LeetCode #958】二叉樹的完全性檢驗(完全二叉樹)
給定一個二叉樹,確定它是否是一個完全二叉樹。 百度百科中對完全二叉樹的定義如下: 若設二叉樹的深度為 h,除第 h 層外,其它各層 (1~h-1) 的結點數都達到最大個數,第 h 層所有的結點都連續集中在最左邊,這就是完全二叉樹。(註:第 h 層可能包含 1~ 2h 個節點。)
解題思路:
使用類似層次遍歷的方法,使用flag標記遇到了nullptr,然後置為true,接着判斷當flag=true時,接下來訪問的節點是否為空,如果都為空,則說明是完全二叉樹,否則不是。 注意:為了將stack中加入nullptr,因此只判斷tmp是否為空即可!
/** * 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 isCompleteTree(TreeNode* root) { bool flag = false; queue<TreeNode*> que; que.push(root); while(!que.empty()) { TreeNode* tmp = que.front(); que.pop(); if (tmp == nullptr) flag = true; if (flag && tmp) return false; // 遇到nullptr,後面都應該是nullptr if (tmp) { // 與層次遍歷不同,只需要判斷tmp是否為nullptr que.push(tmp->left); que.push(tmp->right); } } return true; } };
來源:力扣(LeetCode) 鏈接:https://leetcode-cn.com/problems/check-completeness-of-a-binary-tree
【LeetCode #919】完全二叉樹插入器
完全二叉樹是每一層(除最後一層外)都是完全填充(即,結點數達到最大)的,並且所有的結點都儘可能地集中在左側。 設計一個用完全二叉樹初始化的數據結構 CBTInserter,它支持以下幾種操作:
CBTInserter(TreeNode root) 使用頭結點為 root 的給定樹初始化該數據結構; CBTInserter.insert(int v) 將 TreeNode 插入到存在值為 node.val = v 的樹中以使其保持完全二叉樹的狀態,並返回插入的 TreeNode 的父結點的值; CBTInserter.get_root() 將返回樹的頭結點。
解題思路:
LeetCode上的翻譯很爛,簡單來說,就是現在有一顆root為根節點的完全二叉樹,當我們向二叉樹中插入節點的,也應該保證完全二叉樹的性質,這在裏面使用層次遍歷的方法,尋找某個節點的左節點或者右節點為nullptr的節點,定為待插入節點root_. 注意如果向某個節點的右節點插入了一個節點,那麼待插入節點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 CBTInserter { public: queue<TreeNode*> que; // 注意root為一個完全二叉樹 CBTInserter(TreeNode* root) : root_(root), node_(nullptr) { que.push(root_); while(!que.empty()) { TreeNode* tmp = que.front(); que.pop(); if (tmp->left) que.push(tmp->left); if (tmp->right) que.push(tmp->right); if (node_ == nullptr && (tmp->left == nullptr || tmp->right == nullptr)) { node_ = tmp; break; } } } int insert(int v) { TreeNode* newNode = new TreeNode(v); int father = node_->val; if(node_->left == nullptr) node_->left = newNode; else { node_->right = newNode; if (!que.empty()) { node_ = que.front(); que.pop(); } } return father; } TreeNode* get_root() { return root_; } private: TreeNode* node_; // 用來儲存待插入節點的位置 TreeNode* root_; // 用來儲存樹根節點的位置 };
來源:力扣(LeetCode) 鏈接:https://leetcode-cn.com/problems/complete-binary-tree-inserter