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

歡迎訪問 生活随笔!

生活随笔

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

java

leetcode 235. 二叉搜索树的最近公共祖先(Java版,树形dp套路)

發(fā)布時間:2024/2/28 java 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 leetcode 235. 二叉搜索树的最近公共祖先(Java版,树形dp套路) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目

原題地址:leetcode 235. 二叉搜索樹的最近公共祖先

說明:

  • 所有節(jié)點的值都是唯一的。
  • p、q 為不同節(jié)點且均存在于給定的二叉搜索樹中。

題解

關于 樹形dp 套路,可以參考我的另一篇博客:左神算法:找到二叉樹中的最大搜索二叉子樹(Java版)

下面簡述本題思路:

  • 首先,如何判斷一個節(jié)點 head 是否是 p、q 的公共祖先?只需要用二分查找的方式,判斷以 head 為頭的樹中是否包含 p、q 即可。
  • 然后,如何找到“最近”的公共祖先?直觀上看,最近的公共祖先,一定是所有的公共祖先中 最深的那個。因此,只需要遍歷整個二叉樹,就可以找到最深的公共祖先了,也就是我們所說的最近公共祖先。
  • 總的來說,就是 利用遞歸函數設計一個二叉樹前序遍歷的過程:先收集當前節(jié)點的信息,然后根據當前節(jié)點的信息,去遍歷左子樹(同時更新信息),最后再遍歷右子樹(同時更新信息)

    時間復雜度分析

    因為是遞歸函數,所以對所有的子樹要求一樣,都返回 Record 的實例。依次求出每棵子樹的答案,總答案一定在其中。既然是前序遍歷,則時間復雜度為O(N)。

    代碼如下,完整步驟見 lowestCommonAncestor 函數。

    代碼

    // Definition for a binary tree node. class TreeNode {int val;TreeNode left;TreeNode right;TreeNode(int x) {val = x;} }public class Solution {// for testpublic static void main(String[] args) {TreeNode n0 = new TreeNode(0);TreeNode n1 = new TreeNode(1);TreeNode n2 = new TreeNode(2);TreeNode n3 = new TreeNode(3);TreeNode n4 = new TreeNode(4);TreeNode n5 = new TreeNode(5);TreeNode n6 = new TreeNode(6);TreeNode n7 = new TreeNode(7);TreeNode n8 = new TreeNode(8);TreeNode n9 = new TreeNode(9);n6.left = n2;n6.right = n8;n2.left = n0;n2.right = n4;n4.left = n3;n4.right = n5;n8.left = n7;n8.right = n9;int n = lowestCommonAncestor(n6, n2, n4).val;System.out.println(n); // 答案:2}/*** 自定義記錄結構,方便引用傳遞時改變其值*/static class Record {TreeNode deepestNode; // 最深節(jié)點int deepestDepth; // 最深節(jié)點的深度public Record(TreeNode deepestNode, int deepestDepth) {this.deepestNode = deepestNode;this.deepestDepth = deepestDepth;}}/*** 入口*/public static TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {return preTree(root, p, q, new Record(root, 0), 0).deepestNode;}/*** 前續(xù)遍歷所有二叉樹節(jié)點,找最深且滿足要求的head* (經過leetcode驗證,此處也可以直接改成后序遍歷,不影響結果正確性)* @param head 頭結點* @param p 題目中要找的p* @param q 題目中要找的q* @param record 自定義記錄結構* @param depth 當前深度* @return*/public static Record preTree(TreeNode head, TreeNode p, TreeNode q, Record record, int depth) {if (head == null) {return record;}// 先收集當前節(jié)點的信息depth += 1;if (isBSTNode(head, p) && isBSTNode(head, q)) { // 如果head為根的樹中可以找到p、q,則說明滿足要求if (depth > record.deepestDepth) { // 如果當前head的深度更深,則更新record.deepestNode = head;record.deepestDepth = depth;}}preTree(head.left, p, q, record, depth); // 根據當前節(jié)點信息,前序遞歸左子樹preTree(head.right, p, q, record, depth); // 根據當前節(jié)點信息,前序遞歸右子樹return record;}/*** 在以h為頭結點的樹中,用二叉搜索的方式能否找到節(jié)點n*/public static boolean isBSTNode(TreeNode h, TreeNode n) {if (h == null) {return false;}if (h == n) {return true;}return isBSTNode(h.val > n.val ? h.left : h.right, n);} }

    附:評論區(qū)的簡潔解法

    class Solution {public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {if (root == null) {return null;}if (p.val < root.val && q.val < root.val) {return lowestCommonAncestor(root.left, p, q);}if (p.val > root.val && q.val > root.val) {return lowestCommonAncestor(root.right, p, q);}return root;} }

    總結

    以上是生活随笔為你收集整理的leetcode 235. 二叉搜索树的最近公共祖先(Java版,树形dp套路)的全部內容,希望文章能夠幫你解決所遇到的問題。

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