1. 程式人生 > 實用技巧 >前端程式設計師學好算法系列(八)二叉樹和遞迴

前端程式設計師學好算法系列(八)二叉樹和遞迴

257. 二叉樹的所有路徑
給定一個二叉樹,返回所有從根節點到葉子節點的路徑。

說明: 葉子節點是指沒有子節點的節點。

示例:

輸入:

1
/ \
2 3
\
5

輸出: ["1->2->5", "1->3"]

解釋: 所有根節點到葉子節點的路徑為: 1->2->5, 1->3

解題:

1. root == null 直接return
2. 判斷我們的路徑是否到達到一個葉子節點中if(root.left==null && root.right == null){ } 說明我們到達了一個節點 直接res.push(root.val) 然後返回當前值

3. 我們遞迴 呼叫binaryTreePaths(root.left) 返回左子樹上滿足條件的所有路徑 ,遍歷獲得的路徑 res.push(root.val+'->' lefts[i]) 這樣我們就獲得了我們左子樹上的所有路徑;

4.同樣方法獲取右邊的所有路徑

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @return {string[]}
 
*/ var binaryTreePaths = function(root) { let res = [] if(root ==null){ return [] } if(root.left==null && root.right == null){ res.push(String(root.val)) return res; } let lefts = binaryTreePaths(root.left) for(let i=0;i<lefts.length;i++){ res.push(String(root.val)
+ '->' +lefts[i]) } let rights = binaryTreePaths(root.right) for(let i=0;i<rights.length;i++){ res.push(String(root.val) + '->' +rights[i]) } return res };

437. 路徑總和 III
給定一個二叉樹,它的每個結點都存放著一個整數值。

找出路徑和等於給定數值的路徑總數。

路徑不需要從根節點開始,也不需要在葉子節點結束,但是路徑方向必須是向下的(只能從父節點到子節點)。

二叉樹不超過1000個節點,且節點數值範圍是 [-1000000,1000000] 的整數。

示例:

root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8

10
/ \
5 -3
/ \ \
3 2 11
/ \ \
3 -2 1

返回 3。和等於 8 的路徑有:

1. 5 -> 3
2. 5 -> 2 -> 1
3. -3 -> 11

解題:

1.我們的主函式每次求解需要求解node node.left和node.right 求解node又需要求解其子函式findPath(sum) 和findPath(sum.left)和findPath(sum.right)
2.在findPath中由於node.val 存在負值所以我們不能直接求res = 1 需要 res+=1
3.我們用findPath(root,sum); 求出從根節點出發所有可能的路徑
4. 我們在分別從pathSum(root.left,sum)pathSum(root.right,sum) 從左右節點出發滿足條件的路徑

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @param {number} sum
 * @return {number}
 */
var pathSum = function(root, sum) {
      if(root == null)
        return 0
      let res = findPath(root,sum);
          res += pathSum(root.left,sum);
          res += pathSum(root.right,sum);
          return res
     // 在以node為根節點的二叉樹中,尋找包含node的路徑,和為sum
     // 返回這個路徑的個數
     function findPath(node,num){
         if(node== null){
             return 0
         }
         let res = 0
         if(node.val ==num){
             res +=1;
         }
         res += findPath(node.left,num - node.val);
         res += findPath(node.right,num - node.val);
         return res
     }
};

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

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

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

示例 1:

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

解題:
1.二叉搜尋樹滿足,其任意左節點小於右節點,
2.當p和q分別在根節點的左邊和右邊時 根節點及為最近公共祖先
3.當root.val>p.val && root.val>q.val 在root的左子樹中尋找
4.當root.val<p.val && root.val<q.val 在root的右

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */

/**
 * @param {TreeNode} root
 * @param {TreeNode} p
 * @param {TreeNode} q
 * @return {TreeNode}
 */
var lowestCommonAncestor = function(root, p, q) {
      if(root==null){
           return root
      }
      if(root.val>p.val && root.val>q.val){
        return lowestCommonAncestor(root.left,p,q)
      }
      if(root.val<p.val && root.val<q.val){
        return lowestCommonAncestor(root.right,p,q)
      }
       
      return root

    
    
};

二叉樹的js內容我們就先介紹到這裡