對稱的二叉樹
劍指OFFER題21------按牛客網通過率排序
時間:2018.12.19.2048
作者:Waitt
題目
請實現一個函式,用來判斷一顆二叉樹是不是對稱的。注意,如果一個二叉樹同此二叉樹的映象是同樣的,定義其為對稱的。
時間限制:1秒 空間限制:32768K 熱度指數:111982
解答
思路1:
中序遍歷二叉樹,用向量儲存值(空結點用0代替),從前後遍歷向量,若有不相等的值,則說明為非對稱。
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
class Solution {
public:
vector<int> a;//全域性向量存貯值
void zhon(TreeNode* pRoot)//中序遍歷
{
if(!pRoot)
{
a.push_back(0);//空指標處補0
return;
}
zhon(pRoot->left);
a.push_back(pRoot->val);
zhon(pRoot->right);
}
bool isSymmetrical(TreeNode* pRoot)
{
if(!pRoot)
return 1;
zhon(pRoot);//此處呼叫中序遍歷函式
int i=0;
int j=a.size()-1;
while(i<j)
{
if(a[i]!=a[j])
return 0;
i++;
j--;
}
return 1;
}
};
存在問題:當二叉樹所有值均相等時,則該方法無效。
思路2
可以使用先序遍歷或者後序遍歷,此處以先序遍歷為例:
先用先序遍歷得到一種結果,再用先序遍歷的對稱遍歷再得到一種結果。(空指標處要進行填充處理)
只有兩種遍歷的結果相同,則說明此樹對稱。
先序遍歷:根、左、右。
先序遍歷的對稱:根、右、左。
利用額外兩個向量進行判斷:
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
class Solution {
public:
vector<int> a,b;// a用來儲存先序遍歷的結果,b用來儲存先序遍歷對稱結果
void xian(TreeNode* pRoot)//先序遍歷函式
{
if(!pRoot)
{
a.push_back(0);//空指標處補0
return;
}
a.push_back(pRoot->val);
xian(pRoot->left);
xian(pRoot->right);
}
void xid(TreeNode* pRoot)//先序遍歷的對稱函式
{
if(!pRoot)
{
b.push_back(0);//空指標處補0
return;
}
b.push_back(pRoot->val);
xid(pRoot->right);
xid(pRoot->left);
}
bool isSymmetrical(TreeNode* pRoot)
{
if(!pRoot)
return 1;
xian(pRoot);
xid(pRoot);
int i=0;
if(a.size()!=b.size())
return 0;
for(int i=0;i<a.size();i++)
{
if(a[i]!=b[i])
return 0;
}
return 1;
}
};
不利用額外向量,逐個進行對比,利用同一個樹的兩個指標
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
class Solution {
public:
bool fuzhu(TreeNode* pRoot1,TreeNode* pRoot2)//定義兩個指標引數
{
if(pRoot1==NULL && pRoot2==NULL)//均為空指標時,說明兩個結點相等
return 1;
if(pRoot1==NULL || pRoot2==NULL)//僅有一個空指標時,說明結點肯定不相等
return 0;
if(pRoot1->val!=pRoot2->val)//若兩個結點的值相等,則進行下一步判斷
return 0;
bool l=fuzhu(pRoot1->left,pRoot2->right);//一個結點向左,一個結點向右
bool r=fuzhu(pRoot2->left,pRoot1->right);//與上一步對稱
return l&&r;
}
bool isSymmetrical(TreeNode* pRoot)
{
if(!pRoot)
return 1;
return fuzhu(pRoot,pRoot);
}
};
TIPS
廣度優先搜尋(BFS)與深度優先搜尋(DFS)
深度優先搜尋用棧(stack)來實現,整個過程可以想象成一個倒立的樹形:
1、把根節點壓入棧中。
2、每次從棧中彈出一個元素,搜尋所有在它下一級的元素,把這些元素壓入棧中。並把這個元素記為它下一級元素的前驅。
3、找到所要找的元素時結束程式。
4、如果遍歷整個樹還沒有找到,結束程式。
廣度優先搜尋使用佇列(queue)來實現,整個過程也可以看做一個倒立的樹形:
1、把根節點放到佇列的末尾。
2、每次從佇列的頭部取出一個元素,檢視這個元素所有的下一級元素,把它們放到佇列的末尾。並把這個元素記為它下一級元素的前驅。
3、找到所要找的元素時結束程式。
4、如果遍歷整個樹還沒有找到,結束程式。
相關文章
- 對稱二叉樹二叉樹
- LeetCode 對稱二叉樹LeetCode二叉樹
- 101. 對稱二叉樹二叉樹
- JZ-058-對稱的二叉樹二叉樹
- 每日一練(16):對稱的二叉樹二叉樹
- Leetcode 題解系列 -- 對稱二叉樹(遞迴)LeetCode二叉樹遞迴
- 程式碼隨想錄day14 || 226 翻轉二叉樹,101 對稱二叉樹, 104 二叉樹的最大深度, 111 二叉樹的最小深度二叉樹
- 【C++】判斷一顆二叉樹是否對稱C++二叉樹
- leetcode-101-Symmetric Tree-二叉樹對稱問題LeetCode二叉樹
- 刷題系列 - Python判斷是否映象對稱二叉樹Python二叉樹
- 對稱二叉樹(力扣)圖解、思路與實現二叉樹力扣圖解
- JavaScript實現-LeetCode刷題-【對稱二叉樹】-第101題!!!JavaScriptLeetCode二叉樹
- LeetCode題解(Offer28):判斷二叉樹是否左右對稱(Python)LeetCode二叉樹Python
- 程式碼隨想錄演算法訓練營第十四天|leetcode226. 翻轉二叉樹、leetcode101.對稱二叉樹、leetcode104.二叉樹的最大深度、leetcode111.二叉樹的最小深度演算法LeetCode二叉樹
- 程式碼隨想錄演算法訓練營第十四天| 226.翻轉二叉樹 、101. 對稱二叉樹、104.二叉樹的最大深度 (優先掌握遞迴)、111.二叉樹的最小深度演算法二叉樹遞迴
- CSP歷年複賽題-P5018 [NOIP2018 普及組] 對稱二叉樹二叉樹
- 滿二叉樹、完全二叉樹、平衡二叉樹、二叉搜尋樹(二叉查詢樹)和最優二叉樹二叉樹
- 程式碼隨想錄演算法訓練營第十五天| 226. 翻轉二叉樹 101. 對稱二叉樹演算法二叉樹
- 資料結構中的樹(二叉樹、二叉搜尋樹、AVL樹)資料結構二叉樹
- Leedcode-二叉搜尋樹的最小絕對差
- 排序二叉樹和平衡二叉樹排序二叉樹
- Day21 | 530.二叉搜尋樹的最小絕對差、501.二叉搜尋樹中的眾數 、236. 二叉樹的最近公共祖先二叉樹
- 二叉樹(順序儲存二叉樹,線索化二叉樹)二叉樹
- 二叉樹的子結構、深度以及重建二叉樹二叉樹
- 二叉搜尋樹和二叉樹的最近公共祖先二叉樹
- 二叉樹的映象二叉樹
- 二叉樹的深度二叉樹
- 手擼二叉樹——AVL平衡二叉樹二叉樹
- 手擼二叉樹——二叉查詢樹二叉樹
- 資料結構之樹結構概述(含滿二叉樹、完全二叉樹、平衡二叉樹、二叉搜尋樹、紅黑樹、B-樹、B+樹、B*樹)資料結構二叉樹
- 玩轉二叉樹(樹的遍歷)二叉樹
- 平衡樹和二叉樹的區別二叉樹
- 二叉樹二叉樹
- 【LeetCode-二叉樹】二叉樹前序遍歷LeetCode二叉樹
- 判斷二叉樹是否為滿二叉樹二叉樹
- 資料結構之MySQL獨愛B+樹(二叉樹、AVL樹、紅黑樹、B樹對比)資料結構MySql二叉樹
- 求二叉樹的高度二叉樹
- 二叉樹的性質二叉樹