二叉树层序遍历
二叉树层序遍历的模板
第一种方法看了一遍代码+写 花了16分钟,挺简单的,递归法就先不看了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class Solution { public: vector<vector<int>> levelOrder(TreeNode* root) { queue<TreeNode*> q; if(root!=NULL) q.push(root); vector<vector<int>> res; while(!q.empty()){ int size=q.size(); vector<int> re; for(int i=0;i<size;i++) { TreeNode* node = q.front(); q.pop(); re.push_back(node->val); if(node->left) q.push(node->left); if(node->right) q.push(node->right); } res.push_back(re); } return res; } };
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| # 递归法 class Solution { public: void order(TreeNode* cur, vector<vector<int>>& result, int depth) { if (cur == nullptr) return; if (result.size() == depth) result.push_back(vector<int>()); result[depth].push_back(cur->val); order(cur->left, result, depth + 1); order(cur->right, result, depth + 1); } vector<vector<int>> levelOrder(TreeNode* root) { vector<vector<int>> result; int depth = 0; order(root, result, depth); return result; } };
|
二叉树的层序遍历 II
题目链接:107. 二叉树的层序遍历 II
五分钟结束战斗,就是上一个代码翻一下。但是性能有点慢,又交了一次时间也是超100%了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class Solution { public: vector<vector<int>> levelOrderBottom(TreeNode* root) { queue<TreeNode*> q; if(root!=NULL) q.push(root); vector<vector<int>> res; while(!q.empty()){ int size=q.size(); vector<int> re; for(int i=0;i<size;i++){ TreeNode* node=q.front(); q.pop(); re.push_back(node->val); if(node->left) q.push(node->left); if(node->right) q.push(node->right); } res.push_back(re); } reverse(res.begin(),res.end()); return res; } };
|
二叉树的右视图
题目链接:199. 二叉树的右视图
四分钟解决战斗,思考了不到一分钟。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class Solution { public: vector<int> rightSideView(TreeNode* root) { queue<TreeNode*> q; if(root!=NULL) q.push(root); vector<int> res; while(!q.empty()){ int size=q.size(); vector<int> re; for(int i=0;i<size;i++) { TreeNode* node=q.front(); q.pop(); re.push_back(node->val); if(node->left) q.push(node->left); if(node->right) q.push(node->right); } res.push_back(re[size-1]); } return res; } };
|
二叉树的层平均值
题目链接:637. 二叉树的层平均值
出了一点小插曲,花了五分钟,前边写的q后边写成p了,double第一次用的int忘了改。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class Solution { public: vector<double> averageOfLevels(TreeNode* root) { queue<TreeNode*> q; if(root!=NULL) q.push(root); vector<double> res; while(!q.empty()){ int s=q.size(); double sum=0; for(int i=0;i<s;i++){ TreeNode* node=q.front(); q.pop(); sum+=node->val; if(node->left) q.push(node->left); if(node->right) q.push(node->right); } res.push_back(sum/s); } return res; } };
|
N 叉树的层序遍历
题目链接:429. N 叉树的层序遍历
乍一看以为是第一题,看了一下不太明白孩子是啥意思,就直接看的题解,其实也没多大区别。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class Solution { public: vector<vector<int>> levelOrder(Node* root) { queue<Node*> que; if (root != NULL) que.push(root); vector<vector<int>> result; while (!que.empty()) { int size = que.size(); vector<int> vec; for (int i = 0; i < size; i++) { Node* node = que.front(); que.pop(); vec.push_back(node->val); for (int i = 0; i < node->children.size(); i++) { if (node->children[i]) que.push(node->children[i]); } } result.push_back(vec); } return result;
} };
|
在每个树行中找最大值
题目链接:515. 在每个树行中找最大值
花了8分钟,因为INT_MIN不知道如何操作,本来用的int,然后改成long long一点一点试的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class Solution { public: vector<int> largestValues(TreeNode* root) { queue<TreeNode*> q; if(root!=NULL) q.push(root); vector<int> res; while(!q.empty()){ int s=q.size(); long long m=-1e14; for(int i=0;i<s;i++) { TreeNode* node=q.front(); q.pop(); if(node->val>m) m=node->val; if(node->left) q.push(node->left); if(node->right) q.push(node->right); } res.push_back(m); } return res; } };
|
填充每个节点的下一个右侧节点指针
题目链接:116. 填充每个节点的下一个右侧节点指针
这题没想明白怎么处理,我是应该新建一个什么类型的vector,用int,char,Node类型都不行,然后就直接看题解了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| class Solution { public: Node* connect(Node* root) { if (root == NULL) return NULL; queue<Node*> q; q.push(root); while (!q.empty()) { int size = q.size(); Node* prev = NULL; for (int i = 0; i < size; ++i) { Node* current = q.front(); q.pop(); if (prev != NULL) prev->next = current; prev = current; if (current->left) q.push(current->left); if (current->right) q.push(current->right); } prev->next = NULL; } return root; } };
|
利用next指针逐层处理(优化)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class Solution { public: Node* connect(Node* root) { if (!root) return nullptr; Node* leftmost = root; while (leftmost->left) { Node* curr = leftmost; while (curr) { curr->left->next = curr->right; if (curr->next) { curr->right->next = curr->next->left; } curr = curr->next; } leftmost = leftmost->left; } return root; } };
|
填充每个节点的下一个右侧节点指针 II
题目链接:117. 填充每个节点的下一个右侧节点指针 II
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| class Solution { public: Node* connect(Node* root) { if (root == NULL) return NULL; queue<Node*> q; q.push(root); while (!q.empty()) { int size = q.size(); Node* prev = NULL; for (int i = 0; i < size; ++i) { Node* current = q.front(); q.pop(); if (prev != NULL) prev->next = current; prev = current; if (current->left) q.push(current->left); if (current->right) q.push(current->right); } prev->next = NULL; } return root; } };
|
二叉树的最大深度
题目链接:104. 二叉树的最大深度
虽然简单,但是用这个方法有种高射炮打蚊子的感觉,感觉应该有更简单的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class Solution { public: int maxDepth(TreeNode* root) { queue<TreeNode*> q; if(root!=NULL) q.push(root); int sum=0; while(!q.empty()){ int s=q.size(); sum=sum+1; for(int i=0;i<s;i++){ TreeNode* node=q.front(); q.pop(); if(node->right) q.push(node->right); if(node->left) q.push(node->left); } } return sum; } };
|
递归方法:后序遍历(DFS)
1 2 3 4 5 6 7
| class Solution { public: int maxDepth(TreeNode* root) { if (root == nullptr) return 0; return max(maxDepth(root->left), maxDepth(root->right)) + 1; } };
|
二叉树的最小深度
题目链接:111. 二叉树的最小深度
找第一个没有左右子树的节点的深度。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class Solution { public: int minDepth(TreeNode* root) { if (root == NULL) return 0; int depth = 0; queue<TreeNode*> que; que.push(root); while(!que.empty()) { int size = que.size(); depth++; for (int i = 0; i < size; i++) { TreeNode* node = que.front(); que.pop(); if (node->left) que.push(node->left); if (node->right) que.push(node->right); if (!node->left && !node->right) { return depth; } } } return depth; } };
|
递归
如果 node 是空节点,由于没有节点,返回 0。
如果 node 没有右儿子,那么深度就是左子树的深度加一,即 dfs(node)=dfs(node.left)+1。
如果 node 没有左儿子,那么深度就是右子树的深度加一,即 dfs(node)=dfs(node.right)+1。
如果 node 左右儿子都有,那么分别递归计算左子树的深度,以及右子树的深度,二者取最小值再加一,即 dfs(node)=min(dfs(node.left),dfs(node.right))+1
1 2 3 4 5 6 7 8 9
| class Solution { public: int minDepth(TreeNode *root) { if (root == nullptr) return 0; if (root->right == nullptr) return minDepth(root->left) + 1; if (root->left == nullptr) return minDepth(root->right) + 1; return min(minDepth(root->left), minDepth(root->right)) + 1; } };
|
翻转二叉树
题目链接:226. 翻转二叉树
迭代法:深度优先遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class Solution { public: TreeNode* invertTree(TreeNode* root) { if (root == nullptr) return nullptr; queue<TreeNode*> q; q.push(root); while (!q.empty()) { TreeNode* node = q.front(); q.pop(); TreeNode* temp = node->left; node->left = node->right; node->right = temp; if (node->left) q.push(node->left); if (node->right) q.push(node->right); } return root; } };
|
递归法:
1 2 3 4 5 6 7 8 9 10
| class Solution { public: TreeNode* invertTree(TreeNode* root) { if (root == NULL) return root; swap(root->left, root->right); invertTree(root->left); invertTree(root->right); return root; } };
|
对称二叉树
题目链接:101. 对称二叉树
迭代队列法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| class Solution { public: bool isSymmetric(TreeNode* root) { if (root == NULL) return true; queue<TreeNode*> que; que.push(root->left); que.push(root->right); while (!que.empty()) { TreeNode* leftNode = que.front(); que.pop(); TreeNode* rightNode = que.front(); que.pop(); if (!leftNode && !rightNode) { continue; }
if ((!leftNode || !rightNode || (leftNode->val != rightNode->val))) { return false; } que.push(leftNode->left); que.push(rightNode->right); que.push(leftNode->right); que.push(rightNode->left); } return true; } };
|
迭代栈法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| class Solution { public: bool isSymmetric(TreeNode* root) { if (root == NULL) return true; stack<TreeNode*> st; st.push(root->left); st.push(root->right); while (!st.empty()) { TreeNode* rightNode = st.top(); st.pop(); TreeNode* leftNode = st.top(); st.pop(); if (!leftNode && !rightNode) { continue; } if ((!leftNode || !rightNode || (leftNode->val != rightNode->val))) { return false; } st.push(leftNode->left); st.push(rightNode->right); st.push(leftNode->right); st.push(rightNode->left); } return true; } };
|
递归法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class Solution { public: bool compare(TreeNode* left, TreeNode* right) { if (left == NULL && right != NULL) return false; else if (left != NULL && right == NULL) return false; else if (left == NULL && right == NULL) return true; else if (left->val != right->val) return false;
bool outside = compare(left->left, right->right); bool inside = compare(left->right, right->left); bool isSame = outside && inside; return isSame;
} bool isSymmetric(TreeNode* root) { if (root == NULL) return true; return compare(root->left, root->right); } };
|