LeetCode 101. 對稱二叉樹 思考分析

題目

給定一個二叉樹,檢查它是否是鏡像對稱的。

例如,二叉樹 [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

進階:
你可以運用遞歸和迭代兩種方法解決這個問題嗎?

思路一,超時

層序遍歷,然后如果該結點是空結點,往該層子數組中填0,否則填val;
當此層所有結點都被遍歷了(包括空結點),觀察子數組是否對稱。
然后更新queue,如果該結點為空結點,則它的子結點也是空結點,如果該結點不是空結點,它的子結點根據真實情況填,如果為空也填入NULL。
不過這樣好像超時了,也就無法驗證了。
退出循環的條件是,該層的所有結點都是空結點

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/
class Solution {
public:bool isSymmetric(TreeNode* root) {queue<TreeNode*> que;if(root!=NULL) que.push(root);while(1){//該層結點元素個數 = 該層隊列元素int size = que.size();vector<int> vec;int null_times=0;//這里要使用固定大小的size,不能使用que.size(),因為在處理中que.size是不斷變化的//將這層元素送入隊列中并依次從隊首向隊尾將元素出隊列,每個元素出隊列的同時又將其不為空的子結點送入隊列for(int i =0;i<size;i++){TreeNode* node = que.front();//將隊首元素送入該層結果que.pop();if(node!=NULL) {vec.push_back(node->val);//將左右孩子結點入隊列,作為下一層的元素if(node->left!=NULL) que.push(node->left);else que.push(NULL);if(node->right!=NULL) que.push(node->right);else que.push(NULL);}else{null_times++;vec.push_back(-2147483648);//將左右孩子結點入隊列,作為下一層的元素que.push(NULL);que.push(NULL);} }if(null_times == size) break;int vecsize=vec.size();for(int j=0;j<vecsize/2+1;j++){if(vec[j]!=vec[vecsize-1-j]) return false;}}return true;}
};

思路二,構造翻轉二叉樹,判斷是否相同

先構造一棵反轉二叉樹,然后按順序遍歷這兩棵樹,判斷是否相同。
Leetcode226. 翻轉二叉樹(遞歸、迭代、層序三種解法)
LeetCode 100. 相同的樹 思考分析
不過此處有一個問題,我們當時翻轉二叉樹的操作是在輸入的二叉樹上進行修改的。這樣如果直接isSameTree(root,invertTree(root));
得到的結果都是true。所以我們需要先深復制一個新的二叉樹,然后在新的二叉樹上完成翻轉操作,然后將翻轉后的二叉樹與原本的二叉樹進行判斷。
關于深復制一棵二叉樹:
LintCode 375. 克隆二叉樹(深復制)

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/
class Solution {
public:TreeNode* invertTree(TreeNode* root) {queue<TreeNode*> que;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();TreeNode* tmp;tmp = node->left;node->left = node->right;node->right = tmp;//將左右孩子結點入隊列,作為下一層的元素if(node->left) que.push(node->left);if(node->right) que.push(node->right);}}return root;}bool isSameTree(TreeNode* p, TreeNode* q) {if(p && q){if(p->val == q->val){return isSameTree(p->right,q->right) && isSameTree(p->left,q->left);}else{return false;} }else if(!p && !q){return true;}return false;}TreeNode * preorder(TreeNode * root){if(root==NULL) return NULL;TreeNode * ans;ans=new TreeNode(root->val);if(root->left!=NULL){ans->left=preorder(root->left);}if(root->right!=NULL){ans->right=preorder(root->right);}return ans;}bool isSymmetric(TreeNode* root) {TreeNode *roota;roota=preorder(root);return isSameTree(root,invertTree(roota));}
};

在這里插入圖片描述

參考其他思路

之前的構造的思路會導致空間嚴重浪費,并且時間耗費也較多。
關于二叉樹是否對稱,我們要比較的是根結點的左子樹與右子樹是不是相互翻轉的。遞歸遍歷的時候要同時遍歷兩棵樹,比較兩棵子樹的里側和外側元素是否相同
本題的遍歷順序為后序遍歷,因為要通過遞歸函數的返回值來判斷兩個子樹的內測結點與外側結點是否相等。
一棵樹遍歷順序為左右中,另一棵樹遍歷順序是右左中。這里可以理解為一種回溯的思想。

遞歸法

1、確定遞歸地參數和返回值
參數:該結點的左子樹結點、右子樹結點
返回值:bool類型
bool compare(TreeNode* left,TreeNode* right)
2、確定終止條件
1、左右都為空,返回true
2、左右只有一個為空,返回false
3、左右結點均不為空,比較結點數值,不相同返回false
4、左右結點均不為空,數值相同返回true

if(left == NULL && right==NULL) return true;
else if(left!=NULL && right==NULL) return false;
else if(right!=NULL && left==NULL) return false;
else if(left->val != right->val) return false;

3、確定單層遞歸邏輯
處理左右結點皆不為空且數值相同的情況。
1、比較二叉樹外側是否對稱:傳入左結點的左孩子,右結點的右孩子。
2、比較內側是否對稱,傳入左結點的右孩子,右結點的左孩子。
3、如果左右都對稱就返回true,否則返回false

bool outside = compare(left->left,right->right);	
bool inside = compare(left->right,right->left);
bool isSame = outside && inside;		
return isSame

完整代碼

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/
class Solution {
public:bool compare(TreeNode* left,TreeNode* right){if(left == NULL && right==NULL) return true;else if(left!=NULL && right==NULL) return false;else if(right!=NULL && left==NULL) return false;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);}
};

在這里插入圖片描述

迭代法

這一題的本質是判斷兩個樹是否相互翻轉,并非簡單的遍歷。這里可以使用隊列來比較兩個樹(根結點的左右子樹)是否相互翻轉。

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/
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;}//左右一個結點不為空,或者都不為空但是數值不同,返回falseif((!leftNode || !rightNode || (leftNode->val!=rightNode->val))){return false;}//外側que.push(leftNode->left);   //左左que.push(rightNode->right); //右右//內側que.push(leftNode->right);que.push(rightNode->left);}return true;}
};

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/378018.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/378018.shtml
英文地址,請注明出處:http://en.pswp.cn/news/378018.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

內心能不能寧靜一點,做事能不能堅持一下

內心能不能寧靜一點&#xff0c;做事能不能堅持一下 每次朋友問我怎么樣&#xff0c;我總感覺不好回答&#xff0c;如果說實話我想他們或許是不能理解我的處境的&#xff0c;只能報以“還好”之類的語言&#xff0c;糊弄一下。唯一一次說了實話是&#xff1a;我墜落了&#xff…

直方圖反向投影

通過直方圖反向投影&#xff0c;根據目標衣服顏色的特征來進行定位 cv2.calcHist([roi_hsv],[0,1],None,[32,48],[0,180,0,256])其中[32,48]表示bin的個數&#xff0c;可以修改&#xff0c;當然范圍越小越精確 import cv2 import numpy as np from matplotlib import pyplot …

javascript 排序_JavaScript中的排序方法

javascript 排序There are tons of sorting algorithms available like bubble sort, merge sort, insertion sort etc. You must have implemented some of these in other programming languages like C or C. But in this article, I will be demonstrating the Sorting met…

LeetCode 二叉樹、N叉樹的最大深度與最小深度(遞歸解)

目錄104. 二叉樹的最大深度559. N叉樹的最大深度111. 二叉樹的最小深度之前的筆記中&#xff0c;已經用層序遍歷解決過這個問題了現在試著用深度的解法去求解104. 二叉樹的最大深度 給定一個二叉樹&#xff0c;找出其最大深度。 二叉樹的深度為根節點到最遠葉子節點的最長路徑…

十、模板匹配

一、概念 模板匹配就是在整個圖像區域發現與給定子圖像匹配的小塊區域。 需要首先給定一個模板圖像A&#xff0c;和一個待檢測圖像B。 在待檢測圖像B上&#xff0c;從左往右&#xff0c;從上往下計算待檢測圖像B和模板圖像A所重疊的匹配度&#xff0c;匹配度越高則兩者相同的可…

基于WF的意見征集4(淺析)

接口項目&#xff1a;IClass&#xff08;項目名稱&#xff09; HTHuiFuusing System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Workflow.Runtime;using System.Workflow.Activities;namespace IClass{ /// <summary> /…

那些VisualStudio隱藏的調試功能

VisualStudio是一個強大的調試工具&#xff0c;里面很多隱藏功能少有人問津&#xff0c;但是在特定場景可以節省你很多時間&#xff0c;本文主要介紹一些VisualStudio調試相關的隱藏功能&#xff0c;歡迎大家補充。 運行到指針(Run to cursor) 大多數人用Visual Studio在調試程…

php連接數據庫代碼_PHP代碼連接各種數據庫

php連接數據庫代碼1)用PHP連接MySQL (1) Connecting with MySQL in PHP) <?php$host "localhost";$uname "username";$pw "password";$db "newDB";try {$conn new PDO("mysql:host$host;dbname$db", $uname, $pw);…

【C++ grammar】對象和類(創建對象、對象拷貝、分離聲明與實現)

目錄1、用類創建對象1、面向對象的特征2、對象由什么構成3、如何定義對象4、創建對象并訪問對象成員1. Constructors(構造函數)2. Constructing Objects (創建對象)3. Object Member Access Operator(對象訪問運算符)2、對象拷貝以及分離聲明與實現1、類是一種數據類型1.1. 定義…

十一、圖像二值化

一、二值圖像 其實就是把圖像轉換為只有黑白的兩種顏色圖像&#xff0c;即像素值非零即一 三角閾值二值化 對一個圖像進行操作&#xff0c;獲取圖像的直方圖&#xff0c;找到波峰和波谷進行連線設為線段A&#xff0c;每個點做有關線段A的垂線垂足在線段A上&#xff0c;最后將…

百度地圖LV1.5實踐項目開發工具類bmap.util.jsV1.2

/*** 百度地圖使用工具類-v1.5* * author boonya* date 2013-7-7* address Chengdu,Sichuan,China* email boonyasina.com* company KWT.Shenzhen.Inc.com* notice 有些功能需要加入外部JS庫才能使用&#xff0c;另外還需要申請地圖JS key .* 申請地址&#xff1a;http…

isatty_帶有示例的Python File isatty()方法

isatty文件isatty()方法 (File isatty() Method) isatty() method is an inbuilt method in Python, it is used to check whether a file stream is an interactive or not in Python i.e. a file stream is connected to a terminal device. If a file is connected to a ter…

地毯店 如何辨別地毯的好壞?

在實地選購地毯品牌時&#xff0c;許多地方需要引起注意&#xff0c;而且要顯得專業&#xff0c;這樣才能科學深入地辨別地毯的好壞。比如&#xff0c;辨明拉絞地毯和抽絞地毯兩種工藝的打結方法幾乎相同&#xff0c;只是變絞形式上有所區別。抽絞的方式較古老&#xff0c;一般…

十二、圖像金字塔

一、原理 reduce高斯模糊降采樣 expand擴大卷積 PyrDown&#xff1a;降采樣 PyrUp&#xff1a;還原 二、高斯金字塔 import cv2 import numpy as np from matplotlib import pyplot as pltdef pyramid(image):level 3temp image.copy()pyramid_image []for i in range(le…

java uuid靜態方法_Java UUID toString()方法與示例

java uuid靜態方法UUID類toString()方法 (UUID Class toString() method) toString() method is available in java.util package. toString()方法在java.util包中可用。 toString() method is used for string denotation of this UUID. toString()方法用于此UUID的字符串表示…

LeetCode 110. 平衡二叉樹思考分析

題目 給定一個二叉樹&#xff0c;判斷它是否是高度平衡的二叉樹。 本題中&#xff0c;一棵高度平衡二叉樹定義為&#xff1a; 一個二叉樹每個節點 的左右兩個子樹的高度差的絕對值不超過1。 示例 1: 給定二叉樹 [3,9,20,null,null,15,7] 3 / 9 20 / 15 7 返回 true 。 示例 2…

Redhat配置XDMCP及相關linux命令

為了能夠使用 Xwin32 或 Xmanager 登錄到 Linux 主機所進行的配置。需要首先在linux上進行相關配置 1.“系統”菜單中選擇“管理”下的“登錄屏幕” 2.出現“登錄窗口首選項”窗口。選擇“遠程”選項卡&#xff0c;將“樣式”改為:“與本地相同” 3.選擇“安全”選項卡&#xf…

充實的日子里忙忙碌碌

實習已經有一個多月了&#xff0c;話說這個月發工資就有我的份兒了&#xff0c;哇咔咔~~~感覺忙忙碌碌的生活其實很充實的。工作日每天都是7點10分左右起來&#xff0c;8點半到公司買早飯吃東西&#xff0c;9點上班開工。先羅列要干的東西&#xff0c;然后一項一項完成&#xf…

十三、圖像梯度

一、兩種算子 一階導數—Sobel算子 水平梯度&#xff1a; 垂直梯度&#xff1a; 最終圖像梯度&#xff1a; 二階導數—Laplacian算子 在二階導數的時候&#xff0c;最大變化處的值為零&#xff0c;即邊緣是零值。 常見的拉普拉斯算子&#xff1a;、其所有元素之和為零。…

Java Formatter out()方法與示例

格式化程序類out()方法 (Formatter Class out() method) out() method is available in java.util package. out()方法在java.util包中可用。 out() method is used to get Appendable for the output. out()方法用于獲取輸出的Appendable。 out() method is a non-static meth…