目录
226 - 翻转二叉树
思路
交换每个子树的左右节点
实现方式1、深度优先
使用递归,先处理左子树,再处理右子树;
举例:
4,2,7,1,3,6,9处理顺序:
根节点:4
4的左右子树:2,7交换
7的左右子树:6,9交换 //左子树处理完成
9的左右子树:null, null交换 //return null;
6的左右子树:null, null交换 //return null;
至此左子树处理完成;
2的左右子树:1,3交换
3的左右子树:null,null交换 //return null
1的左右子树:null,null交换 //return null
至此右子树处理完成;
实现方式2、广度优先
一层一层处理遍历,从上往下;
举例:
4,2,7,1,3,6,9
处理顺序:
根节点压入队列queue:4
取出queue.front(), 4的left,right压入队列;
使用取出的front()交换2,7,第二层交换完成 队列元素:7,2
取出7. 压入6,9,交换6,9 队列元素:2,9,6
取出2,压入1,3,交换1,3, 第三层交换完成 队列元素:9,6,3,1
取出9,不压入队列 队列元素:6,3,1
取出6,不压入队列 队列元素:3,1
取出3,不压入队列 队列元素:1
取出1,不压入队列 队列元素:
队列空,循环结束;
提交代码
#include <regex>
#include "queue"
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};
using namespace std;
class CinvertTree {
public:
// 1、递归,深度优先算法
// TreeNode* invertTree(TreeNode* root) {
// if(root == nullptr) return nullptr;
// else
// {
// swap(root->left, root->right);
// if(root->left) invertTree(root->left);
// if(root->right) invertTree(root->right);
// }
// return root;
// }
// 2、模拟栈,广度优先,遍历每个节点,并交换
TreeNode* invertTree(TreeNode* root) {
if(root == nullptr) return nullptr;
{
queue<TreeNode*> Q;
Q.push(root);
while(!Q.empty()){
TreeNode *node = Q.front();
Q.pop();
if(node->left) Q.push(node->left);
if(node->right) Q.push(node->right);
swap(node->left, node->right);
}
}
return root;
}
};
101 - 对称二叉树
思路
对比对称位置元素是否相等,相等则继续往下对比,不等返回false;
实现方式1、广度优先
使用deque,因为对称需要对比对一个元素和最后一个元素;deque可从前后访问;
处理顺序:
压入root 队列元素:1
取出front,back, pop_front, pop_back(需先对队列判空,因为队列只有一个元素时,pop_front之后队列已空,不能使用pop_back),
比较front和back,相等为空continue,不等返回false;
相等不为空,分别push_front,push_back; //队列元素2,2,2,2(这里取出来的front和back都是根节点,所有分别把左右子树都压入了队列,会多比较一次但不影响最终结果)取出front,back2(2 == 2),
1、push_front(4),push_front(3)队列前面压入front的右节点4,再压入front节点3, 2、push_back(3),push_back(4)队列后面压入front的左节点3,再压入front右节点4 //队列元素3,4,2,2,4,3(压入顺序需保证压入队列后还是原来树的对称关系)
取出front,back3,3(3 == 3)
1、两个3的左右子树都为空,不压入元素 队列元素:4,2,2,4
取出front,back4,4(4 == 4)
1、两个4的左右子树都为空,不压入元素 队列元素:2,2
取出front,back2,2(2 == 2) //到这里其实已经遍历完成所有节点了,但是因为之前把根节点当两个节点了,导致还需要再遍历一遍整个树,整个树相当于遍历了两遍,这里可以优化
1、2,2的子树不为空,按之前规则压入3,4,4,3 队列元素:3,4,4,3
......
实现方式2、深度优先-递归
实现一个方法,传入需要对比的两个元素root->left, root->right,一直递归到整个树完成;
因为leetcode给的isSymmetric方法只有一个参数TreeNode* root,所以要自己写一个有两个参数的函数,分别传入左右两个节点:root->left,root->right,从第二层开始遍历,可以规避实现方式1的那种把根节点当两个节点使用的情况,使遍历的节点数减少一倍;
#include <deque>
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};
using namespace std;
class CisSymmetric {
public:
// 1、自己实现,deque,前后第一个和最后一个对比
// bool isSymmetric(TreeNode* root) {
// if(root == nullptr) return true;
// deque<TreeNode*> dq;
// dq.push_back(root);
// while(!dq.empty()){
// TreeNode* front = dq.front();
// TreeNode* back = dq.back();
// dq.pop_front();
// if(!dq.empty())
// dq.pop_back();
//
// if((front == nullptr && back != nullptr) ||
// back == nullptr && front != nullptr) //1空1不空
// return false;
// else if(front == nullptr && back == nullptr){ //2都为空
// continue;
// }
//
// //2都不空
// dq.push_front(front->right);
// dq.push_front(front->left);
// dq.push_back(back->left);
// dq.push_back(back->right);
//
// if(front->val != back->val){
// return false;
// }
//
// }
// return true;
// }
// 2、递归实现
bool isSymmetric(TreeNode* root) {
if (!root)
return true;
return isTwoTreesSymmetric(root->left, root->right);
}
bool isTwoTreesSymmetric(TreeNode* r1, TreeNode* r2) {
if (!r1 && !r2)
return true;
if (r1 && r2 && r1->val == r2->val)
return isTwoTreesSymmetric(r1->left, r2->right) && isTwoTreesSymmetric(r1->right, r2->left);
return false;
}
void test()
{
TreeNode n1(2);
TreeNode n2(3);
TreeNode n3(3);
TreeNode n4(4);
TreeNode n5(5);
// TreeNode n6(4);
TreeNode n7(4);
n1.left = &n2;
n1.right = &n3;
n2.left = &n4;
n2.right = &n5;
n3.left = nullptr;
n3.right = &n7;
bool b = isSymmetric(&n1);
}
};