Recursion on Tree

Recursion on Tree
Q: for each node in a tree, store the number of nodes in its left child subtree
  • way of thinking:
  1. what do you expect from your leaf child/ right child?
    total number of nodes in my left subtree
    total number of nodes in my right subtree
  2. what do you want to do in the current layer?
    store the number of nodes in the left subtree
  3. what do you want to return to your parent?
    same as number 1
def chang_subtree(node):
  if node is None:
    return 0
  left_total = change_subtree(node.left)
  right_total = change_subtree(node.right)
  node.total_left = left_total
  return 1 + left_total + right+total
Q: Find the node with the max difference in the total number of descendents in its left subtree and right subtree.
  • way of thinking:
  1. what do you expect from your leaf child/ right child?
    total number of nodes in my left subtree
    total number of nodes in my right subtree
  2. what do you want to do in the current layer?
    diff = abs(left_total - right_total)
    global_max_diff = max(diff, global_max_diff)
  3. what do you want to return to your parent?
    return 1 + left_total + right_total
global_max = -1
res = None

def node_diff(root):
  if root is None:
    return 0
  left_total = node_diff(root.left)
  right_total = node_diff(root.right)
  global global_max
  global res
  if abs(left_total - right_total) > global_max:
    global_max = abs(left_total - right_total)
    res = root
  return left_total + right_total + 1
Generally, choose root is None as base case. But sometimes, if we need something related to leaf, we need to choose leaf node( root.left is None and root.rightis None) as base case.
Q: Given a binary tree, find its minimum depth.
def minHeight(root):
  if root is None: #edge case
    return 0
  if root.left is None and root.right is None #base case
    return 1
#此處必須選他作為base case否則只有一個(gè)孩子的node會(huì)返回0
  left = minHeight(root.left) if root.left else float('inf') #infinity
  right = minHeight(root.right) if root.right else float('inf')
  return min(left, right) + 1
Q: Given a binary tree, write a function to determine whether this tree is a binary search tree
def BST(root): #這個(gè)function在這里有g(shù)lobal的意味
  if root is None:
    return True
  min = float('-inf')
  max = float('inf')
  return isBST(root, min, max)

def isBST(root, min, max): #check the order of the values in the tree
  if root is None:
    return True
  if roo.val <= min or root.val >= max:
    return False
  return isBST(root.left, min, root.val) and isBST(root.right, root.val, max)

other ideas
a. use inorder traversal

#儲(chǔ)存當(dāng)前上一個(gè)節(jié)點(diǎn)的value到prev中弊予,看它是不是比當(dāng)前value小。對(duì)于root症革,prev node是left始鱼, 對(duì)于right仔掸,prev node是root。所以recursion中先找left医清,執(zhí)行inorder left起暮,存入prev,比較它與當(dāng)前value会烙,然后存當(dāng)前value于prev中负懦,執(zhí)行inorder right
def is ValidBST(root):
  prev = [None]
  res = [True]
  inorder(root, prev, res)
  return res[0]
def inorder(root, prev, res):
  if not root:
    return
  inorder(root.left, prev, res)
  if prev[0] and prev[0] >= root.val:
    res[0] = False
  prev[0] = root.val
  inorder(root.right, prev, res)

b.

  • way of thinking:
  1. what do you expect from your leaf child/ right child?
    left_res: 左子樹是否為BST/左子樹最大值/左子樹最小值
    right_res: 右子樹是否為BST/右子樹最大值/右子樹最小值
  2. what do you want to do in the current layer?
    isBST = left_res.isBST and right_res.isBST and lef_res.max < root.val and right_res.min > root.val
  3. what do you want to return to your parent?
    return (isBST, left_res.min or root.val, right_res.max or root.val)
# in python: 12 or 25 = 12
#                  12 and 25 = 25
# if 25 == if True 和c++用法相同

def isBSTHelper(root):
  if not root:
    return (True, None, None)
  left_res = isBSTHelper(root.left)
  right_res = isBSTHelper(root.right)
  if not left_res[0] or not right_res[0]:
    return (False, None, None)
  if left_res[2] and root.val <= left_res[2]:
    return (False, None, None)
  if right_res[1] and root.val >= right.res[1]:
    return (False, None, None)
  return (True, left_res[1] or root.val, right_res[2] or root.val)
Q: Find the lowest Common Children
  • way of thinking:
  1. what do you expect from your leaf child/ right child?
    LCA found in the children
  2. what do you want to do in the current layer?
    case 1: LCA found in both cases -> current root is LCA
    case 2: LCA found ar one side of children -> LCA found in the children
  3. what do you want to return to your parent?
    LCA found in the children
def LCA(root, p, q)
  if not root:
    return None
  if root == p or root == q:
    return root
  left_res = LCA(root.left, p, q)
  right_res = LCA(root.right, p, q)
  if left_LCA and right_LCA:
    return root
  else if left_res:
    return left_res
  else:
    return right_res
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市柏腻,隨后出現(xiàn)的幾起案子纸厉,更是在濱河造成了極大的恐慌,老刑警劉巖五嫂,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件颗品,死亡現(xiàn)場(chǎng)離奇詭異肯尺,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)躯枢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門则吟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人锄蹂,你說(shuō)我怎么就攤上這事逾滥。” “怎么了败匹?”我有些...
    開(kāi)封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵寨昙,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我掀亩,道長(zhǎng)舔哪,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任槽棍,我火速辦了婚禮捉蚤,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘炼七。我一直安慰自己缆巧,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布豌拙。 她就那樣靜靜地躺著陕悬,像睡著了一般。 火紅的嫁衣襯著肌膚如雪按傅。 梳的紋絲不亂的頭發(fā)上捉超,一...
    開(kāi)封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音唯绍,去河邊找鬼拼岳。 笑死,一個(gè)胖子當(dāng)著我的面吹牛况芒,可吹牛的內(nèi)容都是我干的惜纸。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼绝骚,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼耐版!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起皮壁,我...
    開(kāi)封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤椭更,失蹤者是張志新(化名)和其女友劉穎哪审,沒(méi)想到半個(gè)月后蛾魄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年滴须,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了舌狗。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡扔水,死狀恐怖痛侍,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情魔市,我是刑警寧澤主届,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站待德,受9級(jí)特大地震影響君丁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜将宪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一绘闷、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧较坛,春花似錦印蔗、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至法竞,卻和暖如春除呵,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背爪喘。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工颜曾, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人秉剑。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓泛豪,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親侦鹏。 傳聞我的和親對(duì)象是個(gè)殘疾皇子诡曙,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi閱讀 7,325評(píng)論 0 10
  • 一轉(zhuǎn)眼,春天到了略水,準(zhǔn)備好心態(tài)价卤,出發(fā)。
    義哥0128閱讀 158評(píng)論 0 0
  • 生活在油鹽醬醋中渊涝,一天慎璧,老婆突然贊許地說(shuō):好像我們已經(jīng)很久沒(méi)有吵架了床嫌。我突然驚覺(jué),我已經(jīng)想不起上次吵架是什么時(shí)候胸私,...
    薔薇睥睨閱讀 514評(píng)論 0 6
  • 多想 多想 多想 抱抱你 多想 多想 多想 看著你 也許我們就應(yīng)該再也不見(jiàn) 哪怕有一天偶然的擦肩而過(guò) 我們的距離皺...
    愛(ài)上王子的丑小鴨閱讀 112評(píng)論 0 1
  • 今天在去往圖書館的路上岁疼,想到了他阔涉。很奇怪,這個(gè)明明在我心中都算是翻篇的人物捷绒,卻不自覺(jué)地出現(xiàn)在我的腦海中瑰排。 有關(guān)于他...
    笑笑_feng閱讀 413評(píng)論 0 1