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.

512 lines
13 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 class14;
import java.util.Stack;
// 本题测试链接 : https://leetcode.com/problems/recover-binary-search-tree/
public class Code05_RecoverBinarySearchTree {
// 不要提交这个类
public static class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int v) {
val = v;
}
}
// 如果能过leetcode只需要提交这个方法即可
// 但其实recoverTree2才是正路只不过leetcode没有那么考
public static void recoverTree(TreeNode root) {
TreeNode[] errors = twoErrors(root);
if (errors[0] != null && errors[1] != null) {
int tmp = errors[0].val;
errors[0].val = errors[1].val;
errors[1].val = tmp;
}
}
public static TreeNode[] twoErrors(TreeNode head) {
TreeNode[] ans = new TreeNode[2];
if (head == null) {
return ans;
}
TreeNode cur = head;
TreeNode mostRight = null;
TreeNode pre = null;
TreeNode e1 = null;
TreeNode e2 = 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 (pre != null && pre.val >= cur.val) {
e1 = e1 == null ? pre : e1;
e2 = cur;
}
pre = cur;
cur = cur.right;
}
ans[0] = e1;
ans[1] = e2;
return ans;
}
// 以下的方法提交leetcode是通过不了的但那是因为leetcode的验证方式有问题
// 但其实!以下的方法,才是正路!在结构上彻底交换两个节点,而不是值交换
public static TreeNode recoverTree2(TreeNode head) {
TreeNode[] errs = getTwoErrNodes(head);
TreeNode[] parents = getTwoErrParents(head, errs[0], errs[1]);
TreeNode e1 = errs[0];
TreeNode e1P = parents[0];
TreeNode e1L = e1.left;
TreeNode e1R = e1.right;
TreeNode e2 = errs[1];
TreeNode e2P = parents[1];
TreeNode e2L = e2.left;
TreeNode e2R = e2.right;
if (e1 == head) {
if (e1 == e2P) {
e1.left = e2L;
e1.right = e2R;
e2.right = e1;
e2.left = e1L;
} else if (e2P.left == e2) {
e2P.left = e1;
e2.left = e1L;
e2.right = e1R;
e1.left = e2L;
e1.right = e2R;
} else {
e2P.right = e1;
e2.left = e1L;
e2.right = e1R;
e1.left = e2L;
e1.right = e2R;
}
head = e2;
} else if (e2 == head) {
if (e2 == e1P) {
e2.left = e1L;
e2.right = e1R;
e1.left = e2;
e1.right = e2R;
} else if (e1P.left == e1) {
e1P.left = e2;
e1.left = e2L;
e1.right = e2R;
e2.left = e1L;
e2.right = e1R;
} else {
e1P.right = e2;
e1.left = e2L;
e1.right = e2R;
e2.left = e1L;
e2.right = e1R;
}
head = e1;
} else {
if (e1 == e2P) {
if (e1P.left == e1) {
e1P.left = e2;
e1.left = e2L;
e1.right = e2R;
e2.left = e1L;
e2.right = e1;
} else {
e1P.right = e2;
e1.left = e2L;
e1.right = e2R;
e2.left = e1L;
e2.right = e1;
}
} else if (e2 == e1P) {
if (e2P.left == e2) {
e2P.left = e1;
e2.left = e1L;
e2.right = e1R;
e1.left = e2;
e1.right = e2R;
} else {
e2P.right = e1;
e2.left = e1L;
e2.right = e1R;
e1.left = e2;
e1.right = e2R;
}
} else {
if (e1P.left == e1) {
if (e2P.left == e2) {
e1.left = e2L;
e1.right = e2R;
e2.left = e1L;
e2.right = e1R;
e1P.left = e2;
e2P.left = e1;
} else {
e1.left = e2L;
e1.right = e2R;
e2.left = e1L;
e2.right = e1R;
e1P.left = e2;
e2P.right = e1;
}
} else {
if (e2P.left == e2) {
e1.left = e2L;
e1.right = e2R;
e2.left = e1L;
e2.right = e1R;
e1P.right = e2;
e2P.left = e1;
} else {
e1.left = e2L;
e1.right = e2R;
e2.left = e1L;
e2.right = e1R;
e1P.right = e2;
e2P.right = e1;
}
}
}
}
return head;
}
public static TreeNode[] getTwoErrNodes(TreeNode head) {
TreeNode[] errs = new TreeNode[2];
if (head == null) {
return errs;
}
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode pre = null;
while (!stack.isEmpty() || head != null) {
if (head != null) {
stack.push(head);
head = head.left;
} else {
head = stack.pop();
if (pre != null && pre.val > head.val) {
errs[0] = errs[0] == null ? pre : errs[0];
errs[1] = head;
}
pre = head;
head = head.right;
}
}
return errs;
}
public static TreeNode[] getTwoErrParents(TreeNode head, TreeNode e1, TreeNode e2) {
TreeNode[] parents = new TreeNode[2];
if (head == null) {
return parents;
}
Stack<TreeNode> stack = new Stack<TreeNode>();
while (!stack.isEmpty() || head != null) {
if (head != null) {
stack.push(head);
head = head.left;
} else {
head = stack.pop();
if (head.left == e1 || head.right == e1) {
parents[0] = head;
}
if (head.left == e2 || head.right == e2) {
parents[1] = head;
}
head = head.right;
}
}
return parents;
}
// for test -- print tree
public static void printTree(TreeNode head) {
System.out.println("Binary Tree:");
printInOrder(head, 0, "H", 17);
System.out.println();
}
public static void printInOrder(TreeNode head, int height, String to, int len) {
if (head == null) {
return;
}
printInOrder(head.right, height + 1, "v", len);
String val = to + head.val + 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 boolean isBST(TreeNode head) {
if (head == null) {
return false;
}
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode pre = null;
while (!stack.isEmpty() || head != null) {
if (head != null) {
stack.push(head);
head = head.left;
} else {
head = stack.pop();
if (pre != null && pre.val > head.val) {
return false;
}
pre = head;
head = head.right;
}
}
return true;
}
public static void main(String[] args) {
TreeNode head = new TreeNode(5);
head.left = new TreeNode(3);
head.right = new TreeNode(7);
head.left.left = new TreeNode(2);
head.left.right = new TreeNode(4);
head.right.left = new TreeNode(6);
head.right.right = new TreeNode(8);
head.left.left.left = new TreeNode(1);
printTree(head);
System.out.println(isBST(head));
System.out.println("situation 1");
TreeNode head1 = new TreeNode(7);
head1.left = new TreeNode(3);
head1.right = new TreeNode(5);
head1.left.left = new TreeNode(2);
head1.left.right = new TreeNode(4);
head1.right.left = new TreeNode(6);
head1.right.right = new TreeNode(8);
head1.left.left.left = new TreeNode(1);
printTree(head1);
System.out.println(isBST(head1));
TreeNode res1 = recoverTree2(head1);
printTree(res1);
System.out.println(isBST(res1));
System.out.println("situation 2");
TreeNode head2 = new TreeNode(6);
head2.left = new TreeNode(3);
head2.right = new TreeNode(7);
head2.left.left = new TreeNode(2);
head2.left.right = new TreeNode(4);
head2.right.left = new TreeNode(5);
head2.right.right = new TreeNode(8);
head2.left.left.left = new TreeNode(1);
printTree(head2);
System.out.println(isBST(head2));
TreeNode res2 = recoverTree2(head2);
printTree(res2);
System.out.println(isBST(res2));
System.out.println("situation 3");
TreeNode head3 = new TreeNode(8);
head3.left = new TreeNode(3);
head3.right = new TreeNode(7);
head3.left.left = new TreeNode(2);
head3.left.right = new TreeNode(4);
head3.right.left = new TreeNode(6);
head3.right.right = new TreeNode(5);
head3.left.left.left = new TreeNode(1);
printTree(head3);
System.out.println(isBST(head3));
TreeNode res3 = recoverTree2(head3);
printTree(res3);
System.out.println(isBST(res3));
System.out.println("situation 4");
TreeNode head4 = new TreeNode(3);
head4.left = new TreeNode(5);
head4.right = new TreeNode(7);
head4.left.left = new TreeNode(2);
head4.left.right = new TreeNode(4);
head4.right.left = new TreeNode(6);
head4.right.right = new TreeNode(8);
head4.left.left.left = new TreeNode(1);
printTree(head4);
System.out.println(isBST(head4));
TreeNode res4 = recoverTree2(head4);
printTree(res4);
System.out.println(isBST(res4));
System.out.println("situation 5");
TreeNode head5 = new TreeNode(2);
head5.left = new TreeNode(3);
head5.right = new TreeNode(7);
head5.left.left = new TreeNode(5);
head5.left.right = new TreeNode(4);
head5.right.left = new TreeNode(6);
head5.right.right = new TreeNode(8);
head5.left.left.left = new TreeNode(1);
printTree(head5);
System.out.println(isBST(head5));
TreeNode res5 = recoverTree2(head5);
printTree(res5);
System.out.println(isBST(res5));
System.out.println("situation 6");
TreeNode head6 = new TreeNode(4);
head6.left = new TreeNode(3);
head6.right = new TreeNode(7);
head6.left.left = new TreeNode(2);
head6.left.right = new TreeNode(5);
head6.right.left = new TreeNode(6);
head6.right.right = new TreeNode(8);
head6.left.left.left = new TreeNode(1);
printTree(head6);
System.out.println(isBST(head6));
TreeNode res6 = recoverTree2(head6);
printTree(res6);
System.out.println(isBST(res6));
System.out.println("situation 7");
TreeNode head7 = new TreeNode(5);
head7.left = new TreeNode(4);
head7.right = new TreeNode(7);
head7.left.left = new TreeNode(2);
head7.left.right = new TreeNode(3);
head7.right.left = new TreeNode(6);
head7.right.right = new TreeNode(8);
head7.left.left.left = new TreeNode(1);
printTree(head7);
System.out.println(isBST(head7));
TreeNode res7 = recoverTree2(head7);
printTree(res7);
System.out.println(isBST(res7));
System.out.println("situation 8");
TreeNode head8 = new TreeNode(5);
head8.left = new TreeNode(3);
head8.right = new TreeNode(8);
head8.left.left = new TreeNode(2);
head8.left.right = new TreeNode(4);
head8.right.left = new TreeNode(6);
head8.right.right = new TreeNode(7);
head8.left.left.left = new TreeNode(1);
printTree(head8);
System.out.println(isBST(head8));
TreeNode res8 = recoverTree2(head8);
printTree(res8);
System.out.println(isBST(res8));
System.out.println("situation 9");
TreeNode head9 = new TreeNode(5);
head9.left = new TreeNode(2);
head9.right = new TreeNode(7);
head9.left.left = new TreeNode(3);
head9.left.right = new TreeNode(4);
head9.right.left = new TreeNode(6);
head9.right.right = new TreeNode(8);
head9.left.left.left = new TreeNode(1);
printTree(head9);
System.out.println(isBST(head9));
TreeNode res9 = recoverTree2(head9);
printTree(res9);
System.out.println(isBST(res9));
System.out.println("situation 10");
TreeNode head10 = new TreeNode(5);
head10.left = new TreeNode(3);
head10.right = new TreeNode(6);
head10.left.left = new TreeNode(2);
head10.left.right = new TreeNode(4);
head10.right.left = new TreeNode(7);
head10.right.right = new TreeNode(8);
head10.left.left.left = new TreeNode(1);
printTree(head10);
System.out.println(isBST(head10));
TreeNode res10 = recoverTree2(head10);
printTree(res10);
System.out.println(isBST(res10));
System.out.println("situation 11");
TreeNode head11 = new TreeNode(5);
head11.left = new TreeNode(3);
head11.right = new TreeNode(7);
head11.left.left = new TreeNode(6);
head11.left.right = new TreeNode(4);
head11.right.left = new TreeNode(2);
head11.right.right = new TreeNode(8);
head11.left.left.left = new TreeNode(1);
printTree(head11);
System.out.println(isBST(head11));
TreeNode res11 = recoverTree2(head11);
printTree(res11);
System.out.println(isBST(res11));
System.out.println("situation 12");
TreeNode head12 = new TreeNode(5);
head12.left = new TreeNode(3);
head12.right = new TreeNode(7);
head12.left.left = new TreeNode(8);
head12.left.right = new TreeNode(4);
head12.right.left = new TreeNode(6);
head12.right.right = new TreeNode(2);
head12.left.left.left = new TreeNode(1);
printTree(head12);
System.out.println(isBST(head12));
TreeNode res12 = recoverTree2(head12);
printTree(res12);
System.out.println(isBST(res12));
System.out.println("situation 13");
TreeNode head13 = new TreeNode(5);
head13.left = new TreeNode(3);
head13.right = new TreeNode(7);
head13.left.left = new TreeNode(2);
head13.left.right = new TreeNode(6);
head13.right.left = new TreeNode(4);
head13.right.right = new TreeNode(8);
head13.left.left.left = new TreeNode(1);
printTree(head13);
System.out.println(isBST(head13));
TreeNode res13 = recoverTree2(head13);
printTree(res13);
System.out.println(isBST(res13));
System.out.println("situation 14");
TreeNode head14 = new TreeNode(5);
head14.left = new TreeNode(3);
head14.right = new TreeNode(7);
head14.left.left = new TreeNode(2);
head14.left.right = new TreeNode(8);
head14.right.left = new TreeNode(6);
head14.right.right = new TreeNode(4);
head14.left.left.left = new TreeNode(1);
printTree(head14);
System.out.println(isBST(head14));
TreeNode res14 = recoverTree2(head14);
printTree(res14);
System.out.println(isBST(res14));
}
}