You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

112 lines
2.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package class_2022_03_2_week;
// 如何时间复杂度O(N)额外空间复杂度O(1),解决最低公共祖先问题?
// 测试链接 : https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/
public class Code08_TimeNSpace1LowestCommonAncestor {
// 这个类不要提交
public static class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
}
// 提交以下的方法
// 该方法亮点在于时间复杂度O(N)额外空间复杂度O(1)
public static TreeNode lowestCommonAncestor(TreeNode head, TreeNode o1, TreeNode o2) {
if (findFirst(o1.left, o1, o2) != null || findFirst(o1.right, o1, o2) != null) {
return o1;
}
if (findFirst(o2.left, o1, o2) != null || findFirst(o2.right, o1, o2) != null) {
return o2;
}
TreeNode leftAim = findFirst(head, o1, o2);
TreeNode cur = head;
TreeNode mostRight = null;
TreeNode ans = null;
while (cur != null) {
mostRight = cur.left;
if (mostRight != null) {
while (mostRight.right != null && mostRight.right != cur) {
mostRight = mostRight.right;
}
if (mostRight.right == null) {
mostRight.right = cur;
cur = cur.left;
continue;
} else {
mostRight.right = null;
if (findLeftAim(cur.left, leftAim)) {
if (ans == null && findFirst(leftAim.right, o1, o2) != null) {
ans = leftAim;
}
leftAim = cur;
}
}
}
cur = cur.right;
}
return ans != null ? ans : (findFirst(leftAim.right, o1, o2) != null ? leftAim : head);
}
public static boolean findLeftAim(TreeNode head, TreeNode leftAim) {
TreeNode tail = reverseEdge(head);
TreeNode cur = tail;
boolean ans = false;
while (cur != null) {
if (cur == leftAim) {
ans = true;
}
cur = cur.right;
}
reverseEdge(tail);
return ans;
}
public static TreeNode reverseEdge(TreeNode from) {
TreeNode pre = null;
TreeNode next = null;
while (from != null) {
next = from.right;
from.right = pre;
pre = from;
from = next;
}
return pre;
}
public static TreeNode findFirst(TreeNode head, TreeNode o1, TreeNode o2) {
if (head == null) {
return null;
}
TreeNode cur = head;
TreeNode mostRight = null;
TreeNode first = null;
while (cur != null) {
mostRight = cur.left;
if (mostRight != null) {
while (mostRight.right != null && mostRight.right != cur) {
mostRight = mostRight.right;
}
if (mostRight.right == null) {
if (first == null && (cur == o1 || cur == o2)) {
first = cur;
}
mostRight.right = cur;
cur = cur.left;
continue;
} else {
mostRight.right = null;
}
} else {
if (first == null && (cur == o1 || cur == o2)) {
first = cur;
}
}
cur = cur.right;
}
return first;
}
}