日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

左神算法:在二叉树中找到累加和为指定值的最长路径长度(Java版)

發布時間:2024/2/28 java 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 左神算法:在二叉树中找到累加和为指定值的最长路径长度(Java版) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本題來自左神《程序員代碼面試指南》“在二叉樹中找到累加和為指定值的最長路徑長度”題目。

題目

給定一棵二叉樹的頭節點 head 和一個 32 位整數 sum,二叉樹節點值類型為整型,求累加和為 sum 的最長路徑長度。“路徑” 是指從某個節點往下,每次最多選擇一個孩子節點或者不選所形成的節點鏈。

例如,二叉樹如圖 3-16 所示。

如果 sum=6,那么累加和為 6 的最長路徑為:-3,3,0,6,所以返回 4。
如果 sum=-9,那么累加和為 -9 的最長路徑為:-9,所以返回 1。

注:本題不用考慮節點值相加可能溢出的情況。

題解

相似問題:“求未排序數組中累加和為規定值的最長子數組長度” 問題

如果二叉樹的節點數為N,本文的解法可以做到時間復雜度為O(N),額外空間復雜度為O(h),其中 h 為二叉樹的高度。

具體過程如下:

1.二叉樹頭節點 head 和規定值 sum 已知;生成變量 maxLen,負責記錄累加和等于 sum 的最長路徑長度。
2.生成哈希表sumMap。負責記錄從 head 開始的一條路徑上的累加和出現的情況,累加和也是從 head 節點的值開始累加的。

  • key 值代表某個累加和
  • value 值代表這個累加和在路徑中最早出現的層數。

如果在遍歷到 cur 節點時,我們能夠知道從 head 到 cur 節點這條路徑上的累加和出現的情況,那么求以 cur 節點結尾的累加和為指定值的最長路徑長度就非常容易。究竟如何去更新sumMap,才能夠做到在遍歷到任何一個節點時,都能有從 head 到這個節點的路徑上的累加和出現的情況呢?步驟3 詳細地說明了更新過程。

3.首先在 sumMap 中加入一個記錄 (0,0),它表示累加和 0 不用包括任何節點就可以得到。然后按照二叉樹先序遍歷的方式遍歷節點,遍歷到的當前節點記為 cur,從 head 到 cur 父節點的累加和記為 preSum,cur 所在的層數記為level。將 cur.value+preSum 的值記為 curSum,就是從 head 到 cur 的累加和。

  • 如果 sumMap 中已經包含 curSum 的記錄,則說明 curSum 在上層中已經出現過,那么就不更新sumMap;
  • 如果 sumMap 不包含 curSum 的記錄,則說明curSum 是第一次出現,就把(curSum,level)這個記錄放入sumMap

接下來是求解在必須以 cur 結尾的情況下,累加和為規定值的最長路徑長度,詳細過程這里不再詳述,請讀者閱讀“求未排序數組中累加和為規定值的最長子數組長度”問題。然后是遍歷 cur 左子樹和右子樹的過程,依然按照上述方法使用和更新 sumMap。處理完以cur 為頭節點的子樹,當然要返回 cur 父節點。

在返回前還有一項重要的工作要做,在 sumMap 中查詢 curSum 這個累加和(key)出現的層數(value)

  • 如果 value 等于 level,則說明 curSum 這個累加和的記錄是在遍歷到 cur 時加上去的,那就把這條記錄刪除,目的是 保證 maxLen 在遞歸調用返回時不被污染,以便后續調用繼續使用
  • 如果 value 不等于 level,則不做任何調整。

4.步驟3 會遍歷二叉樹所有的節點,也會求解以每個節點結尾的情況下,累加和為規定值的最長路徑長度。用 maxLen 記錄其中的最大值即可。

代碼

全部求解過程請參看如下代碼中的 getMaxLength 方法。

package chapter_3_binarytreeproblem;import java.util.HashMap;public class Problem_06_LongestPathSum {public static class Node {public int value;public Node left;public Node right;public Node(int data) {this.value = data;}}public static int getMaxLength(Node head, int sum) {HashMap<Integer, Integer> sumMap = new HashMap<Integer, Integer>();sumMap.put(0, 0); // importantreturn preOrder(head, sum, 0, 1, 0, sumMap);}/*** 前序遍歷,返回滿足要求的累加和sum的最長路徑* @param head 當前頭結點* @param sum 指定的累加和* @param preSum 從head到cur父節點的累加和記為preSum* @param level cur所在的層數* @param maxLen 累加和等于sum的最長路徑長度* @param sumMap (key, value) = (累加和, 累加和在路徑中最早出現的層數)* @return*/public static int preOrder(Node head, int sum, int preSum, int level, int maxLen, HashMap<Integer, Integer> sumMap) {if (head == null) {return maxLen;}int curSum = preSum + head.value;if (!sumMap.containsKey(curSum)) { // curSum在上層未出現過,則記錄sumMap.put(curSum, level); // sumMap中存放的,均為從二叉樹【頭結點】開始計算的累加和}if (sumMap.containsKey(curSum - sum)) { // 如果為true,說明從key所在位置到cur位置的累加和正好為sum// 此步驟求 "以cur結尾的情況下,滿足累加和為sum的最長路徑" 的長度// 即,將新的 "從key所在位置到cur位置的路徑長度" 與 "到達此節點前,已經求得的最長路徑長度" 相比較,取較大者maxLen = Math.max(level - sumMap.get(curSum - sum), maxLen);}maxLen = preOrder(head.left, sum, curSum, level + 1, maxLen, sumMap); // 遞歸前序遍歷左子樹maxLen = preOrder(head.right, sum, curSum, level + 1, maxLen, sumMap); // 遞歸前序遍歷右子樹if (level == sumMap.get(curSum)) { // 如果表中curSum這個累加和的記錄是在遍歷到cur時加上去的,則刪除這條記錄// 這樣做的目的是:保證函數返回后sumMap不受到污染// 因為遞歸調用返回到上層函數后,后續可能還有preOrder()調用,還要用到sumMap// (可以類比"求所有排列組合"題目,也是需要在交換兩元素后、返回前,恢復原狀)sumMap.remove(curSum);}return maxLen;}// for test -- print treepublic static void printTree(Node head) {System.out.println("Binary Tree:");printInOrder(head, 0, "H", 17);System.out.println();}public static void printInOrder(Node head, int height, String to, int len) {if (head == null) {return;}printInOrder(head.right, height + 1, "v", len);String val = to + head.value + to;int lenM = val.length();int lenL = (len - lenM) / 2;int lenR = len - lenM - lenL;val = getSpace(lenL) + val + getSpace(lenR);System.out.println(getSpace(height * len) + val);printInOrder(head.left, height + 1, "^", len);}public static String getSpace(int num) {String space = " ";StringBuffer buf = new StringBuffer("");for (int i = 0; i < num; i++) {buf.append(space);}return buf.toString();}public static void main(String[] args) {Node head = new Node(-3);head.left = new Node(3);head.right = new Node(-9);head.left.left = new Node(1);head.left.right = new Node(0);head.left.right.left = new Node(1);head.left.right.right = new Node(6);head.right.left = new Node(2);head.right.right = new Node(1);printTree(head);System.out.println(getMaxLength(head, 6));System.out.println(getMaxLength(head, -9));System.out.println(getMaxLength(head, 9));}}

總結

以上是生活随笔為你收集整理的左神算法:在二叉树中找到累加和为指定值的最长路径长度(Java版)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 一起草在线视频 | 无码h肉动漫在线观看 | 国产九九九九九 | 精品免费在线 | 久久国产精品国语对白 | 99免费精品 | 成人av动漫 | 奇米网久久| 欧美激情在线一区二区 | 日操干 | 色就是色欧美 | 综合网久久 | www九九热 | 91大神网址| 香蕉av一区| 欧美大胆a | 中文字幕久久网 | 久久久久久免费毛片精品 | 久久久久久久久综合 | 五月天中文字幕 | xiuxiuavnet | 成人毛片av | www.青青操| 久操视频在线观看免费 | 午夜av大片 | 999超碰| www.国产精品.com | 精品国产AV色欲天媒传媒 | 亚洲欧美制服丝袜 | 久久免费视频3 | 亚洲欧洲综合 | 国产91精品久久久久久久网曝门 | 国产精品丝袜黑色高跟鞋的设计特点 | 免费在线看黄色片 | 国产成人午夜精品无码区久久 | 欧美国产成人精品一区二区三区 | 色播99 | 精品亚洲aⅴ无码一区二区三区 | av免费看网站 | 亚洲欧洲久久久 | 日韩专区欧美专区 | 久久婷婷一区二区 | 午夜免费福利影院 | 射影院| 欧美成人精品一区二区三区在线观看 | 亚洲av无码一区二区三区网址 | 色涩色| 国产一区二区精彩视频 | 亚洲国产剧情在线观看 | a视频免费观看 | 99精品久久久久久久 | 久久色图 | 青青草综合在线 | 欧美成人h版在线观看 | 欧美自偷自拍 | 亚洲毛茸茸 | www国产com | 欧美动态色图 | 久精品国产 | 青青草综合网 | 午夜黄色大片 | 鬼灭之刃柱训练篇在线观看 | 色老头在线一区二区三区 | 日韩字幕在线 | 精品www久久久久久奶水 | 熟妇五十路六十路息与子 | 欧美日韩精品二区 | 久久久久99精品成人片直播 | 五月婷婷激情综合 | 欧美一区二区三区免费 | 91蜜桃网 | 国内自拍真实伦在线观看 | 俄罗斯av在线| 国产精品福利网站 | 成人h在线观看 | 久久人人爽人人 | 91av日本| 四虎成人在线观看 | 激情视频网 | 欧洲视频一区二区 | 国产精品久久久久久久久免费软件 | 这里只有精品视频在线观看 | 免费网站av | 久色视频在线播放 | 蜜桃成熟时李丽珍在线观看 | 五月激情丁香 | 国产精品九一 | 男男受被啪到高潮自述 | 又色又爽又高潮免费视频国产 | 国产欧美精品 | 日韩少妇毛片 | 欧美一区二区福利视频 | 黄色无遮挡 | 日韩三级免费看 | 日本a在线天堂 | 亚洲激情网| 欧美日韩国产一区二区 | 日本黄页网站 | 欧美猛男gaygay |