給定一個二叉樹,檢查它是否是鏡像對稱的。
例如,二叉樹 [1,2,2,3,4,4,3]
是對稱的。
1 / \ 2 2 / \ / \ 3 4 4 3
但是下面這個 [1,2,2,null,3,null,3]
則不是鏡像對稱的:
1 / \ 2 2 \ \ 3 3
遞歸的難點在於:找到可以遞歸的點 爲什麼很多人覺得遞歸一看就會,一寫就廢。 或者說是自己寫無法寫出來,關鍵就是你對遞歸理解的深不深。
對於此題: 遞歸的點怎麼找?從拿到題的第一時間開始,思路如下:
1.怎麼判斷一棵樹是不是對稱二叉樹? 答案:如果所給根節點,爲空,那麼是對稱。如果不爲空的話,當他的左子樹與右子樹對稱時,他對稱
2.那麼怎麼知道左子樹與右子樹對不對稱呢?在這我直接叫爲左樹和右樹 答案:如果左樹的左孩子與右樹的右孩子對稱,左樹的右孩子與右樹的左孩子對稱,那麼這個左樹和右樹就對稱。
仔細讀這句話,是不是有點繞?怎麼感覺有一個功能A我想實現,但我去實現A的時候又要用到A實現後的功能呢?
當你思考到這裏的時候,遞歸點已經出現了: 遞歸點:我在嘗試判斷左樹與右樹對稱的條件時,發現其跟兩樹的孩子的對稱情況有關係。
想到這裏,你不必有太多疑問,上手去按思路寫代碼,函數A(左樹,右樹)功能是返回是否對稱
def 函數A(左樹,右樹): 左樹節點值等於右樹節點值 且 函數A(左樹的左子樹,右樹的右子樹),函數A(左樹的右子樹,右樹的左子樹)均爲真 才返回真
實現完畢。。。
寫着寫着。。。你就發現你寫出來了。。。。。。
#include <iostream>
using namespace std;
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
bool isSymmetric(TreeNode* root) {
if(root == NULL){
return true;
}
else{
return treeJudge(root -> left, root -> right);
}
}
bool treeJudge(TreeNode* l, TreeNode *r){
if(l == NULL && r == NULL){
return true;
}
if((l == NULL && r != NULL) || (l != NULL && r == NULL)){
return false;
}
if(l -> val == r -> val &&(treeJudge(l -> left, r -> right)) && (treeJudge(l -> right, r -> left))){
return true;
}
else{
return false;
}
}
int main(){
isSymmetric(root)
}