LeetCode0993: 二叉樹的堂兄弟節(jié)點

題目介紹

描述:

在二叉樹中匣距,根節(jié)點位于深度 0 處,每個深度為 k 的節(jié)點的子節(jié)點位于深度 k+1 處上荡。

如果二叉樹的兩個節(jié)點深度相同趴樱,但父節(jié)點不同,則它們是一對堂兄弟節(jié)點酪捡。

我們給出了具有唯一值的二叉樹的根節(jié)點 root叁征,以及樹中兩個不同節(jié)點的值 x 和 y。

只有與值 x 和 y 對應(yīng)的節(jié)點是堂兄弟節(jié)點時逛薇,才返回 true捺疼。否則,返回 false永罚。

解題思路:

遞歸算法的關(guān)鍵是要明確函數(shù)的「定義」是什么啤呼,然后相信這個定義,利用這個定義推導(dǎo)最終結(jié)果呢袱。

寫樹相關(guān)的算法官扣,簡單說就是,先搞清楚當(dāng)前 root 節(jié)點該做什么羞福,然后根據(jù)函數(shù)定義遞歸調(diào)用子節(jié)點惕蹄,遞歸調(diào)用會讓孩子節(jié)點做相同的事情。

二叉樹題目的一個難點在于如何通過題目的要求思考出每一個節(jié)點需要做什么

二叉樹解題策略

一 遞歸 二 隊列 + 迭代 (層次遍歷) 三 棧 + 迭代 (非遞歸遍歷) 四 其它

三種基本的遍歷方式治专,都可以用遞歸來實現(xiàn)卖陵。寫遞歸算法的時候,需要注意遞歸退出條件以及遞歸操作的表達张峰。

自己的解法實現(xiàn)

def isCousins4(self, root, x, y):
        if not root: return []
        stack = [root]
        while stack:
            counter = 0
            for _ in range(len(stack)):
                node = stack.pop(0)
                if node.left and node.right and ((node.left.val == x and node.right.val == y) or (node.left.val == x and node.right.val == y)):
                    return False
                if node.val == x or node.val == y:
                    counter += 1
                    if counter == 2:
                        return True
                if node.left:
                    stack.append(node.left)
                if node.right:
                    stack.append(node.right)

網(wǎng)上比較優(yōu)秀的解法

解法一

方法:標(biāo)記父節(jié)點與深度 思路 當(dāng)且僅當(dāng)一對節(jié)點深度相同而父節(jié)點不相同時泪蔫,它們是堂兄弟節(jié)點。一種非常直接的方法就是通過某種方法求出每一個節(jié)點的深度與父節(jié)點挟炬。

算法 我們用深度優(yōu)先搜索標(biāo)記每一個節(jié)點鸥滨,對于每一個節(jié)點 node嗦哆,它的父親為 par,深度為 d婿滓,我們將其記錄到 Hashmap 中:parent[node.val] = par 且 depth[node.val] = d老速。

def isCousins(self, root, x, y):
        parent = {}
        depth = {}
        def dfs(node, par = None):
            if node:
                depth[node.val] = 1 + depth[par.val] if par else 0
                parent[node.val] = par
                dfs(node.left, node)
                dfs(node.right, node)
        dfs(root)
        return depth[x] == depth[y] and parent[x] != parent[y]

解法二

方法1——深度優(yōu)先搜索 輸出x和y的深度以及它們的父結(jié)點, 然后按照題意比較即可

def __init__(self):
        self.d = 0
        self.node = TreeNode()

    def isCousins2(self, root, x, y):
        def dfs(node, num, tmp):
            if not node: return
            tmp += 1
            if (node.left and node.left.val == num) or (node.right and node.right.val == num):
                self.d = tmp + 1
                self.node = node
                return
            dfs(node.left, num, tmp)
            dfs(node.right, num, tmp)
        dfs(root, x, 0)
        dx, xf = self.d, self.node

        dfs(root, y, 0)
        dy, yf = self.d, self.node

        if dx == dy and xf.val != yf.val:
            return True
        return False

解法三

哈希+BFS

def isCousins3(self, root, x, y):
        queue, hm = [(root, None)], {}  # BFS, 每層掃描完后考察是否找到其中一個點(若找到則跳出)
        while queue and not (x in hm or y in hm):
            n = len(queue)
            for i in range(n):  # 掃描每一層
                node, parent = queue.pop(0)
                if node:  # 把當(dāng)前節(jié)點作為父節(jié)點信息往下傳
                    queue += [(node.left, node), (node.right, node)]
                    hm[node.val] = parent  # 直接哈希記錄父節(jié)點
        return (x in hm and y in hm) and hm[x] != hm[y]  # 同一層且父節(jié)點不同

相關(guān)知識總結(jié)和思考

相關(guān)知識:

BFS:廣度/寬度優(yōu)先凸主。其實就是從上到下橘券,先把每一層遍歷完之后再遍歷一下一層。

可以使用Queue的數(shù)據(jù)結(jié)構(gòu)卿吐。我們將root節(jié)點初始化進隊列旁舰,通過消耗尾部,插入頭部的方式來完成BFS嗡官。

二叉搜索樹(BST)的特性:

  1. 若它的左子樹不為空箭窜,則所有左子樹上的值均小于其根節(jié)點的值
  2. 若它的右子樹不為空,則所有右子樹上的值均大于其根節(jié)點的值
  3. 它的左右子樹也分別為二叉搜索樹

遞歸與迭代的區(qū)別

遞歸:重復(fù)調(diào)用函數(shù)自身實現(xiàn)循環(huán)稱為遞歸衍腥; 迭代:利用變量的原值推出新值稱為迭代磺樱,或者說迭代是函數(shù)內(nèi)某段代碼實現(xiàn)循環(huán);

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末婆咸,一起剝皮案震驚了整個濱河市竹捉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌尚骄,老刑警劉巖块差,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異倔丈,居然都是意外死亡憨闰,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門乃沙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來起趾,“玉大人,你說我怎么就攤上這事警儒。” “怎么了眶根?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵蜀铲,是天一觀的道長。 經(jīng)常有香客問我属百,道長记劝,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任族扰,我火速辦了婚禮厌丑,結(jié)果婚禮上定欧,老公的妹妹穿的比我還像新娘。我一直安慰自己怒竿,他們只是感情好砍鸠,可當(dāng)我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著耕驰,像睡著了一般爷辱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上朦肘,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天饭弓,我揣著相機與錄音,去河邊找鬼媒抠。 笑死弟断,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的趴生。 我是一名探鬼主播夫嗓,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼冲秽!你這毒婦竟也來了舍咖?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤锉桑,失蹤者是張志新(化名)和其女友劉穎排霉,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體民轴,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡攻柠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了后裸。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瑰钮。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖微驶,靈堂內(nèi)的尸體忽然破棺而出浪谴,到底是詐尸還是另有隱情,我是刑警寧澤因苹,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布苟耻,位于F島的核電站,受9級特大地震影響扶檐,放射性物質(zhì)發(fā)生泄漏凶杖。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一款筑、第九天 我趴在偏房一處隱蔽的房頂上張望智蝠。 院中可真熱鬧腾么,春花似錦、人聲如沸杈湾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽毛秘。三九已至饭寺,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間叫挟,已是汗流浹背艰匙。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留抹恳,地道東北人员凝。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像奋献,于是被迫代替她去往敵國和親健霹。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,619評論 2 354