[寶寶也能看懂的活動篇][30-Day LeetCoding Challenge] 第十一天

二叉樹的直徑

Hi 你們好,我是張小豬。歡迎來到『寶寶也能看懂』系列特別篇 - 官方小活動 『30-Day LeetCoding Challenge』。node

這裏是 4 月 11 號的題,也是題目列表中的第 543 題 -- 『二叉樹的直徑』git

題目描述

給定一棵二叉樹,你須要計算它的直徑長度。一棵二叉樹的直徑長度是任意兩個結點路徑長度中的最大值。這條路徑可能穿過也可能不穿過根結點。github

示例 :shell

給定二叉樹

          1
         / \
        2   3
       / \
      4   5

返回 __3__, 它的長度是路徑 [4,2,1,3] 或者 [5,2,1,3]。segmentfault

注意: 兩結點之間的路徑長度是以它們之間邊的數目表示。優化

官方難度

EASYspa

解決思路

題目的需求是求一顆二叉樹的直徑。第一眼看起來彷佛有些不知道如何下手,不過咱們嘗試把這個問題拆解開來。站在一個節點的視角上看來這個目標,那其實只有兩種狀況:code

  • 這個最長路徑以"我"爲轉折點:那麼這個最長路徑必然就是以"我"爲根節點的子樹左側的高度 + 右側的高度 + 1。
  • 這個最長路徑不以"我"爲轉折點:那麼它必定以其餘某個節點爲轉折點,對於"我"無需進行後續計算。

經過這種方式,咱們成功的把目標拆解爲了比較簡單的小目標。而後咱們只須要找到方法求出子樹的高度便可。blog

直接方案

經過深度優先遍歷,咱們能夠輕鬆的求得某個子樹的高度。爲了不大量的重複計算,咱們能夠用一個 map 把運算的結果進行暫存。最後再結合上面的思路,咱們能夠獲得相似下面的代碼:leetcode

const diameterOfBinaryTree = root => {
  const cache = new Map();
  let max = 0;
  dfs(root);
  return max;

  function dfs(node) {
    if (!node) return 0;
    if (cache.has(node)) return cache.get(node);
    const r = dfs(node.right);
    const l = dfs(node.left);
    if (max < r + l) max = r + l;
    cache.set(node, Math.max(r, l) + 1);
    return Math.max(r, l) + 1;
  }
};

總結

分析的過程其實就是嘗試把一個大目標拆分紅不少的小目標來處理。而對於二叉樹,咱們經常使用的經典的遍歷方式例如深度優先遍歷,再結合 memo 來作一點優化。但願能幫助到有須要的小夥伴。

若是以爲不錯的話,記得『三連』哦。小豬愛大家喲~

相關連接

qrcode_green.jpeg

相關文章
相關標籤/搜索