89、【树与二叉树】leetcode ——101. 对称二叉树:后序递归+迭代法+层次遍历(C++版本)
2023-09-11 14:20:01 时间
题目描述
原题链接:101. 对称二叉树
解题思路
一、后序遍历
1、递归
设置两个指针进行遍历对比,分别指向互相对称位置:左子树的左孩子与右子树的右孩子互对称,左子树的右孩子与右子树的左孩子互对称。
每次遍历前先判定对称位置上是否有结点,是否值相同。
(1)当都为空时,说明遍历到底;
(2)当一个为空,另一个不为空时,说明互不对称;
(3)当双方值不相同时,说明互不对称。
然后,再分别让两个指针后续孩子的对称位置进行遍历:左的左与右的右,左的右与右的左。子树判定完,将结果返回给上一层。
/**
* Definition for a binary tree node.
* 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) {}
* };
*/
class Solution {
public:
bool compare(TreeNode* left, TreeNode* right) {
// 左右都为空时,说明遍历到底,返回true
if(!left && !right) return true;
// 一个为空,一个不为空,返回false
if(!left || !right) return false;
// 对称结点不相等,返回false。注意:为了防止空指针异常,这里不能和第一行用||共写
if(left->val != right->val) return false;
// 左结点的左孩子与右结点的右孩子为对称位置,此时遍历为左右中
bool leftcom = compare(left->left, right->right);
// 左结点的右孩子与右结点的左孩子为对称位置,此时遍历为右左中
bool rightcom = compare(left->right, right->left);
return leftcom & rightcom; // 将结果返回给上一层结点
}
bool isSymmetric(TreeNode* root) {
if(!root) return false;
return compare(root->left, root->right);
}
};
2、非递归
每次从栈中弹出两个元素进行操作,这两个元素应分别为互对称位置元素。
然后判定是否为对称元素,不为对称元素则false
,为对称元素则继续遍历。按照对称位置顺序进行压栈,左的左、右的右、左的右、右的左。
/**
* Definition for a binary tree node.
* 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) {}
* };
*/
class Solution {
public:
bool isSymmetric(TreeNode* root) {
if(!root) return false;
stack<TreeNode*> st;
st.push(root->left);
st.push(root->right);
while(!st.empty()) {
TreeNode* leftnode = st.top(); st.pop();
TreeNode* rightnode = st.top(); st.pop();
// 加入到叶节点、左空右不空、左不空右空时判定
if(!leftnode && !rightnode) continue;
if(!leftnode || !rightnode) return false;
if(leftnode->val != rightode->val) return false;
// 注意加入顺序,左的左与右的右互配,左的右与右的左互配,
st.push(leftnode->left);
st.push(rightnode->right);
st.push(leftnode->right);
st.push(righttnode->left);
}
return true;
}
};
二、层次遍历
注意:此时若要用while(n--)
的话,需要n -= 2
。否则会报错
Line 26: Char 30: runtime error: member access within misaligned address 0xbebebebebebebebe for type ‘TreeNode’, which requires 8 byte alignment (solution.cpp)
0xbebebebebebebebe: note: pointer points here
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior prog_joined.cpp:35:30
因为不需要有关层次的信息,因此可以直接用最外层的while
循环即可,不用再求出当前队列中的元素个数,再while(n--)
/**
* Definition for a binary tree node.
* 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) {}
* };
*/
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) return false;
if(leftnode->val != rightnode->val) return false;
que.push(leftnode->left);
que.push(rightnode->right);
que.push(leftnode->right);
que.push(rightnode->left);
}
return true;
}
};
参考文章:101. 对称二叉树
相关文章
- 为什么全网都劝你不要自学C++?
- C++设计模式 ==> 装饰(者)模式
- C++中虚基类在派生类中的内存布局
- 《C++入门经典(第5版•修订版)》——6.5 switch语句
- C++基本要点复习--------coursera程序设计实习(PKU)的lecture notes
- 203、【栈与队列】leetcode ——剑指 Offer II 040. 矩阵中最大的矩形 / 85. 最大矩形:暴力+单调栈(C++/Pyhont版本)
- 189、【动态规划】leetcode ——312. 戳气球(C++版本)
- 187、【栈与队列】leetcode ——42. 接雨水(C++版本)
- 184、【栈与队列】leetcode ——739. 每日温度(C++版本)
- 179、【动态规划】leetcode ——115. 不同的子序列(C++版本)
- 132、【贪心算法】leetcode ——45. 跳跃游戏 II(贪心策略)(C++版本)
- 108、【树与二叉树】leetcode ——235. 二叉搜索树的最近公共祖先:普通树解法+BST性质解法(C++版本)
- 107、【树与二叉树】leetcode ——236. 二叉树的最近公共祖先:回溯法(C++版本)
- 106、【树与二叉树】leetcode ——501. 二叉搜索树中的众数:双指针法+哈希表法(C++版本)
- 103、【树与二叉树】leetcode ——700. 二叉搜索树中的搜索:递归法+迭代法(C++版本)
- 99、【树与二叉树】leetcode ——113. 路径总和 II:回溯法两种版本(C++版本)
- 98、【树与二叉树】leetcode ——112. 路径总和:5行精简代码回溯法[带剪枝]+迭代法(C++版本)
- 96、【树与二叉树】leetcode ——404. 左叶子之和:递归法[先序+后序]+迭代法[先序+层次](C++版本)
- 95、【树与二叉树】leetcode ——257. 二叉树的所有路径:递归法DFS/回溯法+迭代法DFS+层序遍历BFS(C++版本)
- 93、【树与二叉树】leetcode ——222. 完全二叉树的节点个数:普通二叉树求法+完全二叉树性质求法(C++版本)
- 91、【树与二叉树】leetcode ——559.n叉树的最大深度(递归DFS+迭代BFS)(C++版本)
- 采用完成端口(IOCP)实现高性能网络服务器(Windows c++版)
- C++STL 仿函数