依然二叉树。没办法,二叉树实在太重要了。先学广度优先搜索在二叉树中的应用——层序遍历代码随想录。主要思想是用队列模拟,将每层元素数量用size记录,再通过while(size--)控制每层元素的弹出,最后将结果输入到一个二维数组中。下面进入实操环节,共有10道题。
第一题是层序遍历,手撕出了卡哥讲的方法。
class Solution {//层序遍历
public:
vector> levelOrder(TreeNode* root) {
queue que;
vector> result;
if (root != NULL)
que.push(root);
while (!que.empty()) {
int size = que.size();
vector vec;
while (size--) {
TreeNode* node = que.front();
que.pop();
vec.push_back(node->val);
if (node->left)
que.push(node->left);
if (node->right)
que.push(node->right);
}
result.push_back(vec);
}
return result;
}
};
看代码随想录是发现还有递归法,比非递归的代码简洁了不少。
class Solution {
public:
void order(TreeNode* cur, vector>& result, int depth) {
if (cur == nullptr)
return;
if (result.size() == depth)
result.push_back(vector());
result[depth].push_back(cur->val);
order(cur->left, result, depth + 1);
order(cur->right, result, depth + 1);
}
vector> levelOrder(TreeNode* root) {
vector> result;
int depth = 0;
order(root, result, depth);
return result;
}
};
有了以上代码基础,第二题https://leetcode.cn/problems/binary-tree-level-order-traversal-ii/description/就很好写出,前面代码不变,result数组反转即可。
class Solution {
public:
vector> levelOrderBottom(TreeNode* root) {
queue que;
vector> result;
if (root != NULL)
que.push(root);
while (!que.empty()) {
int size = que.size();
vector vec;
while (size--) {
TreeNode* node = que.front();
que.pop();
vec.push_back(node->val);
if (node->left)
que.push(node->left);
if (node->right)
que.push(node->right);
}
result.push_back(vec);
}
reverse(result.begin(), result.end());
return result;
}
};
第三题是二叉树的右视图https://leetcode.cn/problems/binary-tree-right-side-view/description/,只用记录层序遍历中最后一个元素,即size==0的情况,代码稍加修改即可。
class Solution {
public:
vector rightSideView(TreeNode* root) {
vector vec;
queue que;
if (root != NULL)
que.push(root);
while (!que.empty()) {
int size = que.size();
while (size--) {
TreeNode* node = que.front();
que.pop();
if (node->left)
que.push(node->left);
if (node->right)
que.push(node->right);
if (size == 0)
vec.push_back(node->val);
}
}
return vec;
}
};
第四题是二叉树的层平均值https://leetcode.cn/problems/average-of-levels-in-binary-tree/description/,也很简单。
class Solution {
public:
vector averageOfLevels(TreeNode* root) {
vector result;
queue que;
if (root != NULL)
que.push(root);
while (!que.empty()) {
int size = que.size();
double sum = 0;
for (int i = 0; i < size; i++) {
TreeNode* node = que.front();
sum += node->val;
que.pop();
if (node->left)
que.push(node->left);
if (node->right)
que.push(node->right);
}
result.push_back(sum / size);
}
return result;
}
};
第五题是n叉树的层序遍历https://leetcode.cn/problems/n-ary-tree-level-order-traversal/。
class Solution {
public:
vector> levelOrder(Node* root) {
vector> result;
queue que;
if (root != NULL)
que.push(root);
while (!que.empty()) {
int size = que.size();
vector vec;
for (int i = 0; i < size; i++) {
Node* node = que.front();
vec.push_back(node->val);
que.pop();
for (int i = 0; i < node->children.size(); i++) {
if (node->children[i])
que.push(node->children[i]);
}
}
result.push_back(vec);
}
return result;
}
};
第六题是每个树行找最大值https://leetcode.cn/problems/find-largest-value-in-each-tree-row/description/。
class Solution {
public:
vector largestValues(TreeNode* root) {
vector max;
queue que;
if (root != NULL)
que.push(root);
while (!que.empty()) {
int size = que.size();
int a = INT_MIN;
for (int i = 0; i < size; i++) {
TreeNode* node = que.front();
if (node->val > a)
a = node->val;
que.pop();
if (node->left)
que.push(node->left);
if (node->right)
que.push(node->right);
}
max.push_back(a);
}
return max;
}
};
第七题 是填充每个节点的下一个节点指针https://leetcode.cn/problems/populating-next-right-pointers-in-each-node/description/。
class Solution {
public:
Node* connect(Node* root) {
queue que;
if (root != NULL)
que.push(root);
while (!que.empty()) {
int size = que.size();
Node* nodepre;
Node* node;
for (int i = 0; i < size; i++) {
if (i == 0) {
nodepre = que.front();
que.pop();
node = nodepre;
} else {
node = que.front();
que.pop();
nodepre->next = node;
nodepre = nodepre->next;
}
if (node->left)
que.push(node->left);
if (node->right)
que.push(node->right);
if (i == size - 1)
node->next = NULL;
}
}
return root;
}
};
第八题和第七题相同,只是情景设定一个是完美二叉树一个是不完美二叉树,层序遍历的逻辑不变。https://leetcode.cn/problems/populating-next-right-pointers-in-each-node-ii/description/
class Solution {
public:
Node* connect(Node* root) {
queue que;
if(root != NULL) que.push(root);
while(!que.empty()){
int size = que.size();
Node* nodepre;
Node* node;
for(int i = 0; i < size; i++){
if(i == 0) {
nodepre = que.front();
que.pop();
node = nodepre;
}
else{
node = que.front();
que.pop();
nodepre->next = node;
nodepre = nodepre->next;
}
if (i == size - 1) node->next = NULL;
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
}
return root;
}
};
第九题是二叉树的最大深度 https://leetcode.cn/problems/maximum-depth-of-binary-tree/description/,只用定义一个depth变量,每次进入size循环前加一即可。
class Solution {
public:
int maxDepth(TreeNode* root) {
queue que;
int depth = 0;
if (root != NULL)
que.push(root);
while (!que.empty()) {
int size = que.size();
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);
}
depth++;
}
return depth;
}
};
第十题是二叉树的最小深度https://leetcode.cn/problems/minimum-depth-of-binary-tree/,如果层序遍历遇到叶子结点,跳出循环即可。
class Solution {
public:
int minDepth(TreeNode* root) {
int depth = 0;
queue que;
if (root != NULL)
que.push(root);
while (!que.empty()) {
int size = que.size();
depth++;
while (size--) {
TreeNode* node = que.front();
que.pop();
if (node->left == NULL && node->right == NULL)
return depth;
if (node->left)
que.push(node->left);
if (node->right)
que.push(node->right);
}
}
return depth;
}
};
终于把这个层序遍历做完了,泪目了,头一次做这么多题。我要打十个!!!
第11题是翻转二叉树https://leetcode.cn/problems/invert-binary-tree/description/,有点做不动了,直接看卡哥讲解了。
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;
}
};
另外还有迭代法与层序遍历。
class Solution {//前序遍历迭代法
public:
TreeNode* invertTree(TreeNode* root) {
if(root == NULL) return root;
stack st;
st.push(root);
while(!st.empty()){
TreeNode* node = st.top();
st.pop();
swap(node->left, node->right);
if(node->left) st.push(node->left);
if(node->right) st.push(node->right);
}
return root;
}
};
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
queue que;
if (root != NULL) que.push(root);
while(!que.empty()){
int size = que.size();
while(size--){
TreeNode* node = que.front();
que.pop();
swap(node->left, node->right);
if (node->left) que.push(node->left);
if (node->right) que.push(node->right);
}
}
return root;
}
};
最后一题对称二叉树https://leetcode.cn/problems/symmetric-tree/description/,重点是对称的判断与遍历的顺序。
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);
}
};
连做十几题,累坏了哈哈,收获还是很大的,相信再遇到层序遍历就能直接手撕了。