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

2 years ago
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;
}
}