# 剑指 Offer 28. 对称的二叉树
![1692707384014]()
![1692707742822]()
越过叶节点就是传入的指针为空。
| class Solution { |
| public: |
| bool isSymmetric(TreeNode* root) { |
| return root == nullptr || recur(root->left, root->right); |
| } |
| private: |
| bool recur(TreeNode* L, TreeNode* R) { |
| if(L == nullptr && R == nullptr) return true; |
| if(L == nullptr || R == nullptr || L->val != R->val) return false; |
| return recur(L->left, R->right) && recur(L->right, R->left); |
| } |
| }; |
# 剑指 Offer 32 - I. 从上到下打印二叉树
![1692709248141]()
![1692709269363]()
| class Solution { |
| public: |
| vector<int> levelOrder(TreeNode* root) { |
| vector<int> res; |
| if(!root) return res; |
| queue<TreeNode*> que; |
| que.push(root); |
| while(!que.empty()){ |
| TreeNode* node = que.front(); |
| que.pop(); |
| res.push_back(node->val); |
| if(node->left) que.push(node->left); |
| if(node->right) que.push(node->right); |
| } |
| return res; |
| } |
| }; |
# 剑指 Offer 32 - II. 从上到下打印二叉树 II
![1692711272545]()
| |
| * 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<int>> levelOrder(TreeNode* root) { |
| vector<vector<int> > res; |
| |
| if (root == NULL) |
| return res; |
| |
| queue<TreeNode*> q; |
| q.push(root); |
| q.push(NULL); |
| |
| vector<int> temp; |
| TreeNode* temp_ptr; |
| |
| while (!q.empty()) { |
| temp_ptr = q.front(); |
| q.pop(); |
| |
| if (temp_ptr == NULL) { |
| |
| res.push_back(temp); |
| temp.clear(); |
| if (q.size()) { |
| q.push(NULL); |
| } |
| |
| } |
| else { |
| temp.push_back(temp_ptr->val); |
| if (temp_ptr->left) |
| q.push(temp_ptr->left); |
| |
| if (temp_ptr->right) |
| q.push(temp_ptr->right); |
| } |
| } |
| return res; |
| } |
| }; |
上面算法的思路是在队列中,每一层结点之后加一个 NULL 作为标记。
vector 的 push_back 是深拷贝的,所有 temp 清空后,已经 push_back 进入队列的列表不变。
![1692712429574]()
![1692712438812]()
| class Solution { |
| public: |
| vector<vector<int>> levelOrder(TreeNode* root) { |
| queue<TreeNode*> que; |
| vector<vector<int>> res; |
| int cnt = 0; |
| if(root != NULL) que.push(root); |
| while(!que.empty()) { |
| vector<int> tmp; |
| |
| for(int i = que.size(); i > 0; --i) { |
| root = que.front(); |
| que.pop(); |
| tmp.push_back(root->val); |
| if(root->left != NULL) que.push(root->left); |
| if(root->right != NULL) que.push(root->right); |
| } |
| res.push_back(tmp); |
| } |
| return res; |
| } |
| }; |
# 剑指 Offer 32 - III. 从上到下打印二叉树 III
![1692716725551]()
| |
| * 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<int>> levelOrder(TreeNode* root) { |
| vector<vector<int> > res; |
| queue<TreeNode*> q; |
| |
| if (root != NULL) |
| q.push(root); |
| |
| int flag = 1; |
| |
| while (!q.empty()) { |
| TreeNode* p = NULL; |
| |
| vector<int> temp; |
| |
| for (int i = q.size(); i > 0; i--) { |
| p = q.front(); |
| q.pop(); |
| temp.push_back(p->val); |
| |
| if (p->left) |
| q.push(p->left); |
| if (p->right) |
| q.push(p->right); |
| } |
| if (flag) { |
| res.push_back(temp); |
| flag = 0; |
| } |
| else { |
| reverse(temp.begin(), temp.end()); |
| res.push_back(temp); |
| flag = 1; |
| } |
| } |
| return res; |
| |
| } |
| }; |
上面的算法是新添加了一个标记和一个 reverse 函数(用来反转 vector),但返回 vector res 的 size 本身就是一个标记,可以直接用,如下面的解析:
![1692718220134]()
| class Solution { |
| public: |
| vector<vector<int>> levelOrder(TreeNode* root) { |
| deque<TreeNode*> deque; |
| vector<vector<int>> res; |
| if(root != NULL) deque.push_back(root); |
| while(!deque.empty()) { |
| |
| vector<int> tmp; |
| for(int i = deque.size(); i > 0; i--) { |
| |
| TreeNode* node = deque.front(); |
| deque.pop_front(); |
| tmp.push_back(node->val); |
| |
| if(node->left != NULL) deque.push_back(node->left); |
| if(node->right != NULL) deque.push_back(node->right); |
| } |
| res.push_back(tmp); |
| if(deque.empty()) break; |
| |
| tmp.clear(); |
| for(int i = deque.size(); i > 0; i--) { |
| |
| TreeNode* node = deque.back(); |
| deque.pop_back(); |
| tmp.push_back(node->val); |
| |
| if(node->right != NULL) deque.push_front(node->right); |
| if(node->left != NULL) deque.push_front(node->left); |
| } |
| res.push_back(tmp); |
| } |
| return res; |
| } |
| }; |
| class Solution { |
| public: |
| vector<vector<int>> levelOrder(TreeNode* root) { |
| queue<TreeNode*> que; |
| vector<vector<int>> res; |
| if(root != NULL) que.push(root); |
| while(!que.empty()) { |
| vector<int> tmp; |
| for(int i = que.size(); i > 0; i--) { |
| TreeNode* node = que.front(); |
| que.pop(); |
| tmp.push_back(node->val); |
| if(node->left != NULL) que.push(node->left); |
| if(node->right != NULL) que.push(node->right); |
| } |
| if(res.size() % 2 == 1) reverse(tmp.begin(),tmp.end()); |
| res.push_back(tmp); |
| } |
| return res; |
| } |
| }; |
# 剑指 Offer 55 - I. 二叉树的深度
![1692719466029]()
![1692719502269]()
![1692719510682]()
| class Solution { |
| public: |
| int maxDepth(TreeNode* root) { |
| if(root == nullptr) return 0; |
| return max(maxDepth(root->left), maxDepth(root->right)) + 1; |
| } |
| }; |
![1692719883631]()
![1692719892338]()
| class Solution { |
| public: |
| int maxDepth(TreeNode* root) { |
| if(root == nullptr) return 0; |
| vector<TreeNode*> que; |
| que.push_back(root); |
| int res = 0; |
| while(!que.empty()) { |
| vector<TreeNode*> tmp; |
| for(TreeNode* node : que) { |
| if(node->left != nullptr) tmp.push_back(node->left); |
| if(node->right != nullptr) tmp.push_back(node->right); |
| } |
| que = tmp; |
| res++; |
| } |
| return res; |
| } |
| }; |
# 剑指 Offer 54. 二叉搜索树的第 k 大节点
![1692721950163]()
| |
| * 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 kthLargest(TreeNode* root, int k) { |
| recur(root); |
| if (ve.size() < k) { |
| return 0; |
| } |
| else { |
| return ve[k - 1]; |
| } |
| } |
| private: |
| vector<int> ve; |
| void recur(TreeNode* root) { |
| if (root == NULL) |
| return; |
| else { |
| recur(root->right); |
| ve.push_back(root->val); |
| recur(root->left); |
| } |
| } |
| }; |
上面的代码没有使用剪枝
![1692722257324]()
| class Solution { |
| public: |
| int kthLargest(TreeNode* root, int k) { |
| this->k = k; |
| dfs(root); |
| return res; |
| } |
| private: |
| int res, k; |
| void dfs(TreeNode* root) { |
| if(root == nullptr) return; |
| dfs(root->right); |
| if(k == 0) return; |
| if(--k == 0) res = root->val; |
| dfs(root->left); |
| } |
| }; |
# 剑指 Offer 55 - II. 平衡二叉树
![1692723321673]()
![1692723866623]()
![1692723876833]()
| class Solution { |
| public: |
| bool isBalanced(TreeNode* root) { |
| return recur(root) != -1; |
| } |
| private: |
| int recur(TreeNode* root) { |
| if (root == nullptr) return 0; |
| int left = recur(root->left); |
| if(left == -1) return -1; |
| int right = recur(root->right); |
| if(right == -1) return -1; |
| return abs(left - right) < 2 ? max(left, right) + 1 : -1; |
| } |
| }; |
![1692723905175]()
![1692723918958]()
| class Solution { |
| public: |
| bool isBalanced(TreeNode* root) { |
| if (root == nullptr) return true; |
| return abs(depth(root->left) - depth(root->right)) <= 1 && isBalanced(root->left) && isBalanced(root->right); |
| } |
| private: |
| int depth(TreeNode* root) { |
| if (root == nullptr) return 0; |
| return max(depth(root->left), depth(root->right)) + 1; |
| } |
| }; |
# 剑指 Offer 68 - I. 二叉搜索树的最近公共祖先