精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

二叉樹的最近公共祖先

開發 前端
在回溯的過程中,必然要遍歷整顆二叉樹,即使已經找到結果了,依然要把其他節點遍歷完,因為要使用遞歸函數的返回值(也就是代碼中的left和right)做邏輯判斷。

[[419929]]

這道題目的看代碼比較簡單,而且好像也挺好理解的,但是如果把每一個細節理解到位,還是不容易的。

主要思考如下幾點:

  • 如何從底向上遍歷?
  • 遍歷整棵樹,還是遍歷局部樹?
  • 如何把結果傳到根節點的?

這些問題都需要弄清楚,上來直接看代碼的話,是可能想不到這些細節的。

公共祖先問題,還是有難度的,初學者還是需要慢慢消化!

二叉樹的最近公共祖先

力扣鏈接:https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree

給定一個二叉樹, 找到該樹中兩個指定節點的最近公共祖先。

百度百科中最近公共祖先的定義為:“對于有根樹 T 的兩個結點 p、q,最近公共祖先表示為一個結點 x,滿足 x 是 p、q 的祖先且 x 的深度盡可能大(一個節點也可以是它自己的祖先)。”

例如,給定如下二叉樹: root = [3,5,1,6,2,0,8,null,null,7,4]

二叉樹的最近公共祖先

示例 1: 輸入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1 輸出: 3 解釋: 節點 5 和節點 1 的最近公共祖先是節點 3。

示例 2: 輸入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4 輸出: 5 解釋: 節點 5 和節點 4 的最近公共祖先是節點 5。因為根據定義最近公共祖先節點可以為節點本身。

說明:

  • 所有節點的值都是唯一的。
  • p、q 為不同節點且均存在于給定的二叉樹中。

思路

遇到這個題目首先想的是要是能自底向上查找就好了,這樣就可以找到公共祖先了。

那么二叉樹如何可以自底向上查找呢?

回溯啊,二叉樹回溯的過程就是從低到上。

后序遍歷就是天然的回溯過程,最先處理的一定是葉子節點。

接下來就看如何判斷一個節點是節點q和節點p的公共公共祖先呢。

如果找到一個節點,發現左子樹出現結點p,右子樹出現節點q,或者 左子樹出現結點q,右子樹出現節點p,那么該節點就是節點p和q的最近公共祖先。

使用后序遍歷,回溯的過程,就是從低向上遍歷節點,一旦發現如何這個條件的節點,就是最近公共節點了。

遞歸三部曲:

  • 確定遞歸函數返回值以及參數

需要遞歸函數返回值,來告訴我們是否找到節點q或者p,那么返回值為bool類型就可以了。

但我們還要返回最近公共節點,可以利用上題目中返回值是TreeNode * ,那么如果遇到p或者q,就把q或者p返回,返回值不為空,就說明找到了q或者p。

代碼如下:

  1. TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) 
  • 確定終止條件

如果找到了 節點p或者q,或者遇到空節點,就返回。

代碼如下:

  1. if (root == q || root == p || root == NULLreturn root; 
  • 確定單層遞歸邏輯

值得注意的是 本題函數有返回值,是因為回溯的過程需要遞歸函數的返回值做判斷,但本題我們依然要遍歷樹的所有節點。

我們在二叉樹:遞歸函數究竟什么時候需要返回值,什么時候不要返回值?中說了 遞歸函數有返回值就是要遍歷某一條邊,但有返回值也要看如何處理返回值!

如果遞歸函數有返回值,如何區分要搜索一條邊,還是搜索整個樹呢?

搜索一條邊的寫法:

  1. if (遞歸函數(root->left)) return ; 
  2.  
  3. if (遞歸函數(root->right)) return ; 

搜索整個樹寫法:

  1. left = 遞歸函數(root->left); 
  2. right = 遞歸函數(root->right); 
  3. leftright的邏輯處理; 

看出區別了沒?

在遞歸函數有返回值的情況下:如果要搜索一條邊,遞歸函數返回值不為空的時候,立刻返回,如果搜索整個樹,直接用一個變量left、right接住返回值,這個left、right后序還有邏輯處理的需要,也就是后序遍歷中處理中間節點的邏輯(也是回溯)。

那么為什么要遍歷整顆樹呢?直觀上來看,找到最近公共祖先,直接一路返回就可以了。

如圖:

.二叉樹的最近公共祖先

就像圖中一樣直接返回7,多美滋滋。

但事實上還要遍歷根節點右子樹(即使此時已經找到了目標節點了),也就是圖中的節點4、15、20。

因為在如下代碼的后序遍歷中,如果想利用left和right做邏輯處理, 不能立刻返回,而是要等left與right邏輯處理完之后才能返回。

  1. left = 遞歸函數(root->left); 
  2. right = 遞歸函數(root->right); 
  3. leftright的邏輯處理; 

所以此時大家要知道我們要遍歷整棵樹。知道這一點,對本題就有一定深度的理解了。

那么先用left和right接住左子樹和右子樹的返回值,代碼如下:

  1. TreeNode* left = lowestCommonAncestor(root->left, p, q); 
  2. TreeNode* right = lowestCommonAncestor(root->right, p, q); 

如果left 和 right都不為空,說明此時root就是最近公共節點。這個比較好理解。

如果left為空,right不為空,就返回right,說明目標節點是通過right返回的,反之依然。

這里有的同學就理解不了了,為什么left為空,right不為空,目標節點通過right返回呢?

如圖:

二叉樹的最近公共祖先1

圖中節點10的左子樹返回null,右子樹返回目標值7,那么此時節點10的處理邏輯就是把右子樹的返回值(最近公共祖先7)返回上去!

這里點也很重要,可能刷過這道題目的同學,都不清楚結果究竟是如何從底層一層一層傳到頭結點的。

那么如果left和right都為空,則返回left或者right都是可以的,也就是返回空。

代碼如下:

  1. if (left == NULL && right != NULLreturn right
  2. else if (left != NULL && right == NULLreturn left
  3. else  { //  (left == NULL && right == NULL
  4.     return NULL

那么尋找最小公共祖先,完整流程圖如下:

二叉樹的最近公共祖先2

從圖中,大家可以看到,我們是如何回溯遍歷整顆二叉樹,將結果返回給頭結點的!

整體代碼如下:

  1. class Solution { 
  2. public
  3.     TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { 
  4.         if (root == q || root == p || root == NULLreturn root; 
  5.         TreeNode* left = lowestCommonAncestor(root->left, p, q); 
  6.         TreeNode* right = lowestCommonAncestor(root->right, p, q); 
  7.         if (left != NULL && right != NULLreturn root; 
  8.  
  9.         if (left == NULL && right != NULLreturn right
  10.         else if (left != NULL && right == NULLreturn left
  11.         else  { //  (left == NULL && right == NULL
  12.             return NULL
  13.         } 
  14.  
  15.     } 
  16. }; 

稍加精簡,代碼如下:

  1. class Solution { 
  2. public
  3.     TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { 
  4.         if (root == q || root == p || root == NULLreturn root; 
  5.         TreeNode* left = lowestCommonAncestor(root->left, p, q); 
  6.         TreeNode* right = lowestCommonAncestor(root->right, p, q); 
  7.         if (left != NULL && right != NULLreturn root; 
  8.         if (left == NULLreturn right
  9.         return left
  10.     } 
  11. }; 

總結

這道題目刷過的同學未必真正了解這里面回溯的過程,以及結果是如何一層一層傳上去的。

那么我給大家歸納如下三點:

求最小公共祖先,需要從底向上遍歷,那么二叉樹,只能通過后序遍歷(即:回溯)實現從低向上的遍歷方式。

在回溯的過程中,必然要遍歷整顆二叉樹,即使已經找到結果了,依然要把其他節點遍歷完,因為要使用遞歸函數的返回值(也就是代碼中的left和right)做邏輯判斷。

要理解如果返回值left為空,right不為空為什么要返回right,為什么可以用返回right傳給上一層結果。

可以說這里每一步,都是有難度的,都需要對二叉樹,遞歸和回溯有一定的理解。

本題沒有給出迭代法,因為迭代法不適合模擬回溯的過程。理解遞歸的解法就夠了。

其他語言版本

Java

class Solution {

public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {

return lowestCommonAncestor1(root, p, q);

}

public TreeNode lowestCommonAncestor1(TreeNode root, TreeNode p, TreeNode q) {

if (root == null || root == p || root == q) {

return root;

}

TreeNode left = lowestCommonAncestor1(root.left, p, q);

TreeNode right = lowestCommonAncestor1(root.right, p, q);

if (left != null && right != null) {// 左右子樹分別找到了,說明此時的root就是要求的結果

return root;

}

if (left == null) {

return right;

}

return left;

}

}

// 代碼精簡版

class Solution {

public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {

if (root == null || root.val == p.val ||root.val == q.val) return root;

TreeNode left = lowestCommonAncestor(root.left,p,q);

TreeNode right = lowestCommonAncestor(root.right,p,q);

if (left != null && right != null) return root;

else if (left == null && right != null) return right;

else if (left != null && right == null) return left;

else return null;

}

}

Python

//遞歸

class Solution:

def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':

if not root or root == p or root == q: return root //找到了節點p或者q,或者遇到空節點

left = self.lowestCommonAncestor(root.left,p,q) //左

right = self.lowestCommonAncestor(root.right,p,q) //右

if left and right: return root //中: left和right不為空,root就是最近公共節點

elif left and not right: return left //目標節點是通過left返回的

elif not left and right: return right //目標節點是通過right返回的

 

else: return None //沒找到

 

責任編輯:武曉燕 來源: 代碼隨想錄
相關推薦

2021-09-28 06:28:51

二叉樹公共祖先

2021-08-31 11:35:24

二叉搜索樹迭代法公共祖先

2020-04-27 07:05:58

二叉樹左子樹右子樹

2021-04-19 07:47:42

數據結構二叉樹Tree

2021-04-20 08:37:14

數據結構二叉樹

2021-04-28 20:12:27

數據結構創建

2022-10-26 23:58:02

二叉樹數組算法

2021-03-17 08:19:22

二叉樹LeetCode

2013-07-15 16:35:55

二叉樹迭代器

2021-09-29 10:19:00

算法平衡二叉樹

2020-09-23 18:25:40

算法二叉樹多叉樹

2018-03-15 08:31:57

二叉樹存儲結構

2021-10-12 09:25:11

二叉樹樹形結構

2021-09-15 07:56:32

二叉樹層次遍歷

2021-05-06 17:46:30

二叉樹數據結構

2021-03-22 08:23:29

LeetCode二叉樹節點

2023-05-08 15:57:16

二叉樹數據結構

2021-11-29 10:40:58

二叉樹鏡像節點

2020-12-22 08:56:51

JavaScript數據結構前端

2021-07-13 14:03:24

二叉樹滿二叉樹完全二叉樹
點贊
收藏

51CTO技術棧公眾號

亚洲一区精品视频在线观看| 欧美国产日韩免费| jizzjizzxxxx| 你懂的在线观看| 日韩影院精彩在线| 最近2019免费中文字幕视频三| 欧美v在线观看| 大地资源中文在线观看免费版 | 国产精品12p| 国产精品欧美亚洲| 欧美涩涩视频| 精品亚洲精品福利线在观看| 天天天干夜夜夜操| 黄网址在线观看| kk眼镜猥琐国模调教系列一区二区| 日本一本a高清免费不卡| 日韩欧美在线视频播放| 伊人久久大香线蕉av超碰| 欧美视频在线免费看| 午夜久久资源| 亚洲av无码国产精品久久不卡 | 国产性70yerg老太| 日韩欧美黄色| 欧美丰满美乳xxx高潮www| 日本丰满大乳奶| 五月婷婷丁香网| 卡一卡二国产精品 | 中文字幕在线视频播放| 国产一区一一区高清不卡| 亚洲欧美激情在线| 蜜桃传媒视频麻豆第一区免费观看 | 久久99久久久久久| 91.xxx.高清在线| av不卡在线播放| 国产精品自产拍在线观| 日本三级欧美三级| 国产一区不卡| 精品国产免费人成电影在线观看四季 | 久草精品视频在线观看| 色喇叭免费久久综合网| 亚洲国产另类久久精品| 三上悠亚在线一区二区| 欧美激情网站| 亚洲一区二区三区三| 亚洲欧美国产精品桃花| 同心难改在线观看| 东方欧美亚洲色图在线| 国产精品视频网站| 免费观看成人毛片| 亚洲国产一区二区三区高清| 日韩视频一区在线| 国产 欧美 在线| heyzo欧美激情| 欧美一区二区三区啪啪| 美女网站色免费| 午夜精品成人av| 欧美日韩一区二区精品| 久久免费视频2| 都市激情在线视频| 久久综合色一综合色88| 精品国产免费一区二区三区| 精品久久久久久亚洲综合网站| 久久精品国产秦先生| 日韩免费在线视频| 日本少妇久久久| 亚洲精品黄色| 久久久久久久久久久久久久久久久久av| 欧美另类videoxo高潮| 精品久久久中文字幕| 亚洲美女精品成人在线视频| 黄色性视频网站| 哺乳挤奶一区二区三区免费看| 91精品国产入口在线| 一级黄色免费毛片| 欧美一区一区| 精品国产制服丝袜高跟| 九九九久久久久久久| 欧美h版在线观看| 91麻豆精品久久久久蜜臀| 日本r级电影在线观看| 国产精品久久久久久久久久白浆 | 国产精品看片资源| 伊人网av在线| 精品无码三级在线观看视频 | 天堂网一区二区| 丝袜亚洲精品中文字幕一区| 国产精品久久久久久久久久新婚 | 99久久人妻无码中文字幕系列| 亚洲天堂日韩在线| 在线播放日韩专区| 午夜三级在线观看| 欧美国产另类| 午夜精品一区二区三区av| 久久艹免费视频| 日韩精品电影一区亚洲| 91精品国产综合久久久久久蜜臀 | 欧美日韩高清在线| 欧美日韩久久婷婷| 成人在线超碰| 亚洲小视频在线| 侵犯稚嫩小箩莉h文系列小说| 韩国精品一区二区三区| 97热精品视频官网| 无码日韩精品一区二区| 经典三级在线一区| 国产无套精品一区二区| 精品久久av| 最好看的中文字幕久久| 婷婷无套内射影院| 久久亚洲人体| 亚洲激情中文字幕| 欧美激情视频二区| 99久久99久久精品国产片桃花| 久久久亚洲精品视频| 极品国产91在线网站| 国产在线播精品第三| 久久久www免费人成黑人精品| 98在线视频| 午夜视频在线观看一区| 中文字幕视频在线免费观看| 99re热精品视频| 中文国产成人精品久久一| 美女福利视频在线观看| 91久久综合| 国产精品老牛影院在线观看| 亚洲男女视频在线观看| 亚洲国产精品黑人久久久| 日韩久久久久久久久久久久| 成人福利片在线| 日韩成人av在线| 成人免费视频国产免费观看| 亚洲一区视频| 粉嫩av一区二区三区免费观看| 日韩在线免费播放| 亚洲成人免费看| 亚洲热在线视频| 成人羞羞视频播放网站| 97香蕉超级碰碰久久免费软件 | 大桥未久在线播放| 欧美久久久久中文字幕| 国产精成人品免费观看| 亚洲欧美一级二级三级| 91久久久亚洲精品| 午夜视频在线看| 日韩欧美亚洲范冰冰与中字| 男男一级淫片免费播放| 一区二区三区在线观看免费| 国产精品免费久久久| 猫咪在线永久网站| 午夜精品成人在线| 免费黄色av网址| 欧美一区不卡| 国产欧美一区二区三区在线看| 九色视频在线播放| 亚洲精品v日韩精品| 五月婷婷六月丁香激情| av一区二区在线播放| 日本成人精品在线| 三级国产在线观看| 色综合天天天天做夜夜夜夜做| 大尺度做爰床戏呻吟舒畅| 亚洲影视一区| 亚洲综合国产精品| gogo在线高清视频| 日韩一区二区三区免费看| 日本女人性生活视频| 蜜桃av一区二区| 日韩欧美精品一区二区三区经典| free欧美| 国产一区二区三区直播精品电影| 欧美性猛交xxxx乱大交hd | 国产吞精囗交久久久| 国产精品www994| 国产欧美日韩在线播放| av成人影院在线| 日韩av在线网| 99久久久无码国产精品免费蜜柚| 国产欧美一二三区| 在线观看亚洲色图| 五月开心六月丁香综合色啪| 91亚洲精品久久久久久久久久久久| 黄色网页在线免费看| 精品国产一区二区亚洲人成毛片| 9999热视频| 成人精品鲁一区一区二区| xxxx18hd亚洲hd捆绑| 小说区图片区色综合区| 国产精品99久久久久久久久 | 国产一区免费看| 国产精品每日更新在线播放网址| 亚洲欧美日韩三级| 亚洲最黄网站| 亚洲欧美日韩不卡一区二区三区| 国产视频一区二区在线播放| 欧美国产精品人人做人人爱| 先锋av资源站| 欧美日韩综合在线| 国产盗摄x88av| 99久久er热在这里只有精品66| jizzjizz国产精品喷水| 第一sis亚洲原创| 亚洲一区亚洲二区亚洲三区| 啊啊啊久久久| 一本一本久久a久久精品牛牛影视 一本色道久久综合亚洲精品小说 一本色道久久综合狠狠躁篇怎么玩 | 亚洲一级不卡视频| 中文字幕在线观看的网站| 蜜臀av性久久久久av蜜臀妖精| 国产树林野战在线播放| 老司机在线精品视频| 国产高清在线不卡| 天堂va在线| 亚洲小视频在线| 国产 欧美 自拍| 欧美亚洲精品一区| 国产精品男女视频| 亚洲美腿欧美偷拍| 99久久久无码国产精品性 | 少妇欧美激情一区二区三区| 亚久久调教视频| 中文字幕在线乱| 精品国产精品国产偷麻豆| 91超碰在线电影| 亚洲成人va| 国语自产精品视频在线看一大j8 | 无码人妻精品一区二| 国产精品美女视频| 亚洲国产综合视频| 国产在线精品一区二区三区不卡| www.四虎成人| 国模 一区 二区 三区| 免费在线观看一区二区| 精品国产午夜肉伦伦影院| 成人激情视频在线| 激情都市亚洲| 韩国日本不卡在线| 免费的黄网站在线观看| 国产一区二区三区在线看| 蜜桃久久一区二区三区| 欧美一区二区三区四区五区 | 91精品国产免费| 久久久久久无码午夜精品直播| 亚洲三级视频在线观看| 偷拍夫妻性生活| 96av麻豆蜜桃一区二区| 欧美熟妇精品一区二区| 国产主播一区二区| 99re精彩视频| 美女网站色91| 91激情视频在线| 一区二区三区四区五区精品视频 | 女同毛片一区二区三区| 成人小视频在线观看| 超级砰砰砰97免费观看最新一期 | 555www成人网| 俺来也官网欧美久久精品| 欧美另类极品videosbest最新版本 | 看电视剧不卡顿的网站| 15—17女人毛片| 日韩精品每日更新| 日韩免费高清在线| 免费视频一区| 亚洲欧美另类动漫| 日本aⅴ亚洲精品中文乱码| 麻豆av免费在线| 久久精品一区二区三区中文字幕| 99爱视频在线| 奶水喷射视频一区| 日韩精品免费播放| 日韩av不卡在线观看| 成人三级视频在线播放| 日本欧美一区二区| 国产一级特黄a大片免费| 日韩精品视频网站| 欧美婷婷精品激情| 极品销魂美女一区二区三区| 成人免费黄色av| 成人一道本在线| 性欧美18—19sex性高清| 91美女视频网站| 亚洲精品成人无码| 中文字幕欧美激情一区| 婷婷社区五月天| 亚洲乱码一区二区三区在线观看| 免费在线一级片| 亚洲高清免费视频| 日本视频免费观看| 欧洲精品在线观看| 国产麻豆免费观看| 欧美精品一区二区在线播放| 日本韩国一区| 色吧影院999| 人人澡人人添人人爽一区二区| 91国产视频在线| 成人h在线观看| 91青草视频久久| 超碰97久久国产精品牛牛| 激情久久av| 日韩欧美二区| 成年人网站国产| 青青草国产成人99久久| 欧美人与性动交α欧美精品| 国产成人免费高清| 日本免费福利视频| 中文一区在线播放| 久久久久亚洲天堂| 欧美这里有精品| 亚洲国产视频一区二区三区| 在线观看日韩专区| 在线观看免费视频你懂的| 91精品国产高清自在线看超| 91国拍精品国产粉嫩亚洲一区| 99精品国产高清在线观看| 国产欧美日韩| aa视频在线播放| 麻豆精品91| 亚洲中文字幕无码av| 国产精品国产a级| 久久久国产高清| 91精品国产综合久久久久久| 日韩欧美亚洲系列| 九九热最新视频//这里只有精品 | 亚洲第一成年网| 亚洲最大成人在线视频| 日韩精品视频三区| 波多野结衣在线高清| 亚洲va欧美va在线观看| 精品一区二区三| 男人插女人视频在线观看| 美女视频网站久久| 亚欧洲乱码视频| 亚洲女人****多毛耸耸8| 在线免费看91| 亚洲偷欧美偷国内偷| 麻豆视频在线观看免费网站黄| 91久久国产精品| 日本一二区不卡| 精品丰满人妻无套内射| 国产一区二区美女诱惑| 国产精品一区二区亚洲| 一本到高清视频免费精品| 国精产品乱码一区一区三区四区| 久久中文字幕在线| 在线成人视屏| 欧美日韩三区四区| 136国产福利精品导航网址| 男女av免费观看| 久久久久久久久久美女| 国产精品自拍视频一区| 日韩欧美在线不卡| 国产鲁鲁视频在线观看特色| 国产精品免费小视频| 精品国产精品国产偷麻豆| 欧美精品无码一区二区三区| 91蝌蚪porny| 免费黄色网址在线| 日韩国产在线看| 欧美裸体视频| 精品国产免费一区二区三区| 99综合在线| 久久午夜福利电影| 欧洲一区在线观看| 91在线品视觉盛宴免费| 国产在线精品播放| 亚洲成人最新网站| 波多野结衣xxxx| 亚洲精品视频免费观看| 精品乱子伦一区二区| 欧美极品美女视频网站在线观看免费| 精品国产第一国产综合精品| 中文字幕av日韩精品| 国产一区二区h| 亚洲激情视频一区| 亚洲精品一区久久久久久| 亚洲成人看片| 亚洲五月六月| 国产一区二区成人久久免费影院 | 综合激情婷婷| 日本一区二区免费视频| 五月天国产精品| 午夜影院免费体验区| 国产成人拍精品视频午夜网站| 欧美第十八页| 韩国一区二区三区四区| 亚洲成a人在线观看| 欧美偷拍视频| 国产精品极品美女粉嫩高清在线| 手机在线一区二区三区| 国产精品一区二区人妻喷水| 色猫猫国产区一区二在线视频| 亚洲1卡2卡3卡4卡乱码精品| 亚洲a成v人在线观看| 亚洲电影在线| 亚洲av无码国产精品久久| 宅男噜噜噜66一区二区66| 99riav视频在线观看| 亚洲第一综合| 国产成人av资源| 天天射天天干天天| 欧美激情一级二级| 国内成人精品|