leetcode 235. 二叉搜索树的最近公共祖先(Java版,树形dp套路)
生活随笔
收集整理的這篇文章主要介紹了
leetcode 235. 二叉搜索树的最近公共祖先(Java版,树形dp套路)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目
原題地址:leetcode 235. 二叉搜索樹的最近公共祖先
說明:
- 所有節點的值都是唯一的。
- p、q 為不同節點且均存在于給定的二叉搜索樹中。
題解
關于 樹形dp 套路,可以參考我的另一篇博客:左神算法:找到二叉樹中的最大搜索二叉子樹(Java版)
下面簡述本題思路:
總的來說,就是 利用遞歸函數設計一個二叉樹前序遍歷的過程:先收集當前節點的信息,然后根據當前節點的信息,去遍歷左子樹(同時更新信息),最后再遍歷右子樹(同時更新信息)。
時間復雜度分析
因為是遞歸函數,所以對所有的子樹要求一樣,都返回 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; // 最深節點int deepestDepth; // 最深節點的深度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;}/*** 前續遍歷所有二叉樹節點,找最深且滿足要求的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;}// 先收集當前節點的信息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); // 根據當前節點信息,前序遞歸左子樹preTree(head.right, p, q, record, depth); // 根據當前節點信息,前序遞歸右子樹return record;}/*** 在以h為頭結點的樹中,用二叉搜索的方式能否找到節點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);} }附:評論區的簡潔解法
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套路)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 左神算法:未排序正数数组中累加和为给定值
- 下一篇: leetcode 237. 删除链表中的