commit
cbc319092f
@ -0,0 +1,2 @@
|
||||
# 项目排除路径
|
||||
/out/
|
@ -0,0 +1,8 @@
|
||||
# 默认忽略的文件
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# 基于编辑器的 HTTP 客户端请求
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
@ -0,0 +1,17 @@
|
||||
<component name="libraryTable">
|
||||
<library name="Java EE 6-Java EE 6">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/lib/javax.transaction.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/javax.annotation.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/javax.servlet.jsp.jstl.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/javax.jms.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/javax.resource.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/javax.servlet.jsp.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/javax.servlet.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/javax.ejb.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/javax.persistence.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="openjdk-17" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/AlgorithmZuo.iml" filepath="$PROJECT_DIR$/AlgorithmZuo.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Java EE 6-Java EE 6" level="project" />
|
||||
</component>
|
||||
</module>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,110 @@
|
||||
package class01;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class Code02_BubbleSort {
|
||||
|
||||
public static void bubbleSort(int[] arr) {
|
||||
if (arr == null || arr.length < 2) {
|
||||
return;
|
||||
}
|
||||
// 0 ~ N-1
|
||||
// 0 ~ N-2
|
||||
// 0 ~ N-3
|
||||
for (int e = arr.length - 1; e > 0; e--) { // 0 ~ e
|
||||
for (int i = 0; i < e; i++) {
|
||||
if (arr[i] > arr[i + 1]) {
|
||||
swap(arr, i, i + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 交换arr的i和j位置上的值
|
||||
public static void swap(int[] arr, int i, int j) {
|
||||
arr[i] = arr[i] ^ arr[j];
|
||||
arr[j] = arr[i] ^ arr[j];
|
||||
arr[i] = arr[i] ^ arr[j];
|
||||
}
|
||||
|
||||
// for test
|
||||
public static void comparator(int[] arr) {
|
||||
Arrays.sort(arr);
|
||||
}
|
||||
|
||||
// for test
|
||||
public static int[] generateRandomArray(int maxSize, int maxValue) {
|
||||
int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
// for test
|
||||
public static int[] copyArray(int[] arr) {
|
||||
if (arr == null) {
|
||||
return null;
|
||||
}
|
||||
int[] res = new int[arr.length];
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
res[i] = arr[i];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// for test
|
||||
public static boolean isEqual(int[] arr1, int[] arr2) {
|
||||
if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {
|
||||
return false;
|
||||
}
|
||||
if (arr1 == null && arr2 == null) {
|
||||
return true;
|
||||
}
|
||||
if (arr1.length != arr2.length) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < arr1.length; i++) {
|
||||
if (arr1[i] != arr2[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// for test
|
||||
public static void printArray(int[] arr) {
|
||||
if (arr == null) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
System.out.print(arr[i] + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
// for test
|
||||
public static void main(String[] args) {
|
||||
int testTime = 500000;
|
||||
int maxSize = 100;
|
||||
int maxValue = 100;
|
||||
boolean succeed = true;
|
||||
for (int i = 0; i < testTime; i++) {
|
||||
int[] arr1 = generateRandomArray(maxSize, maxValue);
|
||||
int[] arr2 = copyArray(arr1);
|
||||
bubbleSort(arr1);
|
||||
comparator(arr2);
|
||||
if (!isEqual(arr1, arr2)) {
|
||||
succeed = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
System.out.println(succeed ? "Nice!" : "Fucking fucked!");
|
||||
|
||||
int[] arr = generateRandomArray(maxSize, maxValue);
|
||||
printArray(arr);
|
||||
bubbleSort(arr);
|
||||
printArray(arr);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
package class01;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class Code04_BSExist {
|
||||
|
||||
public static boolean exist(int[] sortedArr, int num) {
|
||||
if (sortedArr == null || sortedArr.length == 0) {
|
||||
return false;
|
||||
}
|
||||
int L = 0;
|
||||
int R = sortedArr.length - 1;
|
||||
int mid = 0;
|
||||
// L..R
|
||||
while (L < R) { // L..R 至少两个数的时候
|
||||
mid = L + ((R - L) >> 1);
|
||||
if (sortedArr[mid] == num) {
|
||||
return true;
|
||||
} else if (sortedArr[mid] > num) {
|
||||
R = mid - 1;
|
||||
} else {
|
||||
L = mid + 1;
|
||||
}
|
||||
}
|
||||
return sortedArr[L] == num;
|
||||
}
|
||||
|
||||
// for test
|
||||
public static boolean test(int[] sortedArr, int num) {
|
||||
for(int cur : sortedArr) {
|
||||
if(cur == num) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// for test
|
||||
public static int[] generateRandomArray(int maxSize, int maxValue) {
|
||||
int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int testTime = 500000;
|
||||
int maxSize = 10;
|
||||
int maxValue = 100;
|
||||
boolean succeed = true;
|
||||
for (int i = 0; i < testTime; i++) {
|
||||
int[] arr = generateRandomArray(maxSize, maxValue);
|
||||
Arrays.sort(arr);
|
||||
int value = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
|
||||
if (test(arr, value) != exist(arr, value)) {
|
||||
succeed = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
System.out.println(succeed ? "Nice!" : "Fucking fucked!");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
package class01;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class Code06_BSAwesome {
|
||||
|
||||
// 课上的代码
|
||||
public static int getLessIndex(int[] arr) {
|
||||
if (arr == null || arr.length == 0) {
|
||||
return -1;
|
||||
}
|
||||
if (arr.length == 1 || arr[0] < arr[1]) {
|
||||
return 0;
|
||||
}
|
||||
if (arr[arr.length - 1] < arr[arr.length - 2]) {
|
||||
return arr.length - 1;
|
||||
}
|
||||
int left = 1;
|
||||
int right = arr.length - 2;
|
||||
int mid = 0;
|
||||
while (left < right) {
|
||||
mid = (left + right) / 2;
|
||||
if (arr[mid] > arr[mid - 1]) {
|
||||
right = mid - 1;
|
||||
} else if (arr[mid] > arr[mid + 1]) {
|
||||
left = mid + 1;
|
||||
} else {
|
||||
return mid;
|
||||
}
|
||||
}
|
||||
return left;
|
||||
}
|
||||
|
||||
// 验证得到的结果,是不是局部最小
|
||||
public static boolean isRight(int[] arr, int index) {
|
||||
if (arr.length <= 1) {
|
||||
return true;
|
||||
}
|
||||
if (index == 0) {
|
||||
return arr[index] < arr[index + 1];
|
||||
}
|
||||
if (index == arr.length - 1) {
|
||||
return arr[index] < arr[index - 1];
|
||||
}
|
||||
return arr[index] < arr[index - 1] && arr[index] < arr[index + 1];
|
||||
}
|
||||
|
||||
// 为了测试
|
||||
// 生成相邻不相等的数组
|
||||
public static int[] generateRandomArray(int maxSize, int maxValue) {
|
||||
int[] arr = new int[(int) (Math.random() * maxSize) + 1];
|
||||
arr[0] = (int) (Math.random() * maxValue) - (int) (Math.random() * maxValue);
|
||||
for (int i = 1; i < arr.length; i++) {
|
||||
do {
|
||||
arr[i] = (int) (Math.random() * maxValue) - (int) (Math.random() * maxValue);
|
||||
} while (arr[i] == arr[i - 1]);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
// 为了测试
|
||||
public static void main(String[] args) {
|
||||
int testTime = 500000;
|
||||
int maxSize = 30;
|
||||
int maxValue = 100;
|
||||
System.out.println("测试开始");
|
||||
for (int i = 0; i < testTime; i++) {
|
||||
int[] arr = generateRandomArray(maxSize, maxValue);
|
||||
// Arrays.sort(arr);
|
||||
int ans = getLessIndex(arr);
|
||||
if (!isRight(arr, ans)) {
|
||||
System.out.println("出错了!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
System.out.println("测试结束");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package class01;
|
||||
|
||||
public class Code08_GetMax {
|
||||
|
||||
public static int getMax(int[] arr) {
|
||||
return process(arr, 0, arr.length - 1);
|
||||
}
|
||||
|
||||
public static int process(int[] arr, int L, int R) {
|
||||
if (L == R) {
|
||||
return arr[L];
|
||||
}
|
||||
int mid = L + ((R - L) >> 1);
|
||||
int leftMax = process(arr, L, mid);
|
||||
int rightMax = process(arr, mid + 1, R);
|
||||
return Math.max(leftMax, rightMax);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package class01;
|
||||
|
||||
public class Code09_FindOneLessValueIndex {
|
||||
|
||||
public static int getLessIndex(int[] arr) {
|
||||
if (arr == null || arr.length == 0) {
|
||||
return -1; // no exist
|
||||
}
|
||||
if (arr.length == 1 || arr[0] < arr[1]) {
|
||||
return 0;
|
||||
}
|
||||
if (arr[arr.length - 1] < arr[arr.length - 2]) {
|
||||
return arr.length - 1;
|
||||
}
|
||||
int left = 1;
|
||||
int right = arr.length - 2;
|
||||
int mid = 0;
|
||||
while (left < right) {
|
||||
mid = (left + right) / 2;
|
||||
if (arr[mid] > arr[mid - 1]) {
|
||||
right = mid - 1;
|
||||
} else if (arr[mid] > arr[mid + 1]) {
|
||||
left = mid + 1;
|
||||
} else {
|
||||
return mid;
|
||||
}
|
||||
}
|
||||
return left;
|
||||
}
|
||||
|
||||
public static void printArray(int[] arr) {
|
||||
for (int i = 0; i != arr.length; i++) {
|
||||
System.out.print(arr[i] + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int[] arr = { 6, 5, 3, 4, 6, 7, 8 };
|
||||
printArray(arr);
|
||||
int index = getLessIndex(arr);
|
||||
System.out.println("index: " + index + ", value: " + arr[index]);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
package class02;
|
||||
|
||||
public class Code01_Swap {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int a = 16;
|
||||
int b = 603;
|
||||
|
||||
System.out.println(a);
|
||||
System.out.println(b);
|
||||
|
||||
|
||||
a = a ^ b;
|
||||
b = a ^ b;
|
||||
a = a ^ b;
|
||||
|
||||
|
||||
System.out.println(a);
|
||||
System.out.println(b);
|
||||
|
||||
|
||||
|
||||
|
||||
int[] arr = {3,1,100};
|
||||
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
|
||||
arr[i] = arr[i] ^ arr[j];
|
||||
arr[j] = arr[i] ^ arr[j];
|
||||
arr[i] = arr[i] ^ arr[j];
|
||||
|
||||
System.out.println(arr[i] + " , " + arr[j]);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
System.out.println(arr[0]);
|
||||
System.out.println(arr[2]);
|
||||
|
||||
swap(arr, 0, 0);
|
||||
|
||||
System.out.println(arr[0]);
|
||||
System.out.println(arr[2]);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static void swap (int[] arr, int i, int j) {
|
||||
// arr[0] = arr[0] ^ arr[0];
|
||||
arr[i] = arr[i] ^ arr[j];
|
||||
arr[j] = arr[i] ^ arr[j];
|
||||
arr[i] = arr[i] ^ arr[j];
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,221 @@
|
||||
package class03;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Code01_ReverseList {
|
||||
|
||||
public static class Node {
|
||||
public int value;
|
||||
public Node next;
|
||||
|
||||
public Node(int data) {
|
||||
value = data;
|
||||
}
|
||||
}
|
||||
|
||||
public static class DoubleNode {
|
||||
public int value;
|
||||
public DoubleNode last;
|
||||
public DoubleNode next;
|
||||
|
||||
public DoubleNode(int data) {
|
||||
value = data;
|
||||
}
|
||||
}
|
||||
|
||||
// head
|
||||
// a -> b -> c -> null
|
||||
// c -> b -> a -> null
|
||||
public static Node reverseLinkedList(Node head) {
|
||||
Node pre = null;
|
||||
Node next = null;
|
||||
while (head != null) {
|
||||
next = head.next;
|
||||
head.next = pre;
|
||||
pre = head;
|
||||
head = next;
|
||||
}
|
||||
return pre;
|
||||
}
|
||||
|
||||
public static DoubleNode reverseDoubleList(DoubleNode head) {
|
||||
DoubleNode pre = null;
|
||||
DoubleNode next = null;
|
||||
while (head != null) {
|
||||
next = head.next;
|
||||
head.next = pre;
|
||||
head.last = next;
|
||||
pre = head;
|
||||
head = next;
|
||||
}
|
||||
return pre;
|
||||
}
|
||||
|
||||
public static Node testReverseLinkedList(Node head) {
|
||||
if (head == null) {
|
||||
return null;
|
||||
}
|
||||
ArrayList<Node> list = new ArrayList<>();
|
||||
while (head != null) {
|
||||
list.add(head);
|
||||
head = head.next;
|
||||
}
|
||||
list.get(0).next = null;
|
||||
int N = list.size();
|
||||
for (int i = 1; i < N; i++) {
|
||||
list.get(i).next = list.get(i - 1);
|
||||
}
|
||||
return list.get(N - 1);
|
||||
}
|
||||
|
||||
public static DoubleNode testReverseDoubleList(DoubleNode head) {
|
||||
if (head == null) {
|
||||
return null;
|
||||
}
|
||||
ArrayList<DoubleNode> list = new ArrayList<>();
|
||||
while (head != null) {
|
||||
list.add(head);
|
||||
head = head.next;
|
||||
}
|
||||
list.get(0).next = null;
|
||||
DoubleNode pre = list.get(0);
|
||||
int N = list.size();
|
||||
for (int i = 1; i < N; i++) {
|
||||
DoubleNode cur = list.get(i);
|
||||
cur.last = null;
|
||||
cur.next = pre;
|
||||
pre.last = cur;
|
||||
pre = cur;
|
||||
}
|
||||
return list.get(N - 1);
|
||||
}
|
||||
|
||||
// for test
|
||||
public static Node generateRandomLinkedList(int len, int value) {
|
||||
int size = (int) (Math.random() * (len + 1));
|
||||
if (size == 0) {
|
||||
return null;
|
||||
}
|
||||
size--;
|
||||
Node head = new Node((int) (Math.random() * (value + 1)));
|
||||
Node pre = head;
|
||||
while (size != 0) {
|
||||
Node cur = new Node((int) (Math.random() * (value + 1)));
|
||||
pre.next = cur;
|
||||
pre = cur;
|
||||
size--;
|
||||
}
|
||||
return head;
|
||||
}
|
||||
|
||||
// for test
|
||||
public static DoubleNode generateRandomDoubleList(int len, int value) {
|
||||
int size = (int) (Math.random() * (len + 1));
|
||||
if (size == 0) {
|
||||
return null;
|
||||
}
|
||||
size--;
|
||||
DoubleNode head = new DoubleNode((int) (Math.random() * (value + 1)));
|
||||
DoubleNode pre = head;
|
||||
while (size != 0) {
|
||||
DoubleNode cur = new DoubleNode((int) (Math.random() * (value + 1)));
|
||||
pre.next = cur;
|
||||
cur.last = pre;
|
||||
pre = cur;
|
||||
size--;
|
||||
}
|
||||
return head;
|
||||
}
|
||||
|
||||
// for test
|
||||
public static List<Integer> getLinkedListOriginOrder(Node head) {
|
||||
List<Integer> ans = new ArrayList<>();
|
||||
while (head != null) {
|
||||
ans.add(head.value);
|
||||
head = head.next;
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
// for test
|
||||
public static boolean checkLinkedListReverse(List<Integer> origin, Node head) {
|
||||
for (int i = origin.size() - 1; i >= 0; i--) {
|
||||
if (!origin.get(i).equals(head.value)) {
|
||||
return false;
|
||||
}
|
||||
head = head.next;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// for test
|
||||
public static List<Integer> getDoubleListOriginOrder(DoubleNode head) {
|
||||
List<Integer> ans = new ArrayList<>();
|
||||
while (head != null) {
|
||||
ans.add(head.value);
|
||||
head = head.next;
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
// for test
|
||||
public static boolean checkDoubleListReverse(List<Integer> origin, DoubleNode head) {
|
||||
DoubleNode end = null;
|
||||
for (int i = origin.size() - 1; i >= 0; i--) {
|
||||
if (!origin.get(i).equals(head.value)) {
|
||||
return false;
|
||||
}
|
||||
end = head;
|
||||
head = head.next;
|
||||
}
|
||||
for (int i = 0; i < origin.size(); i++) {
|
||||
if (!origin.get(i).equals(end.value)) {
|
||||
return false;
|
||||
}
|
||||
end = end.last;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// for test
|
||||
public static void main(String[] args) {
|
||||
int len = 50;
|
||||
int value = 100;
|
||||
int testTime = 100000;
|
||||
System.out.println("test begin!");
|
||||
for (int i = 0; i < testTime; i++) {
|
||||
Node node1 = generateRandomLinkedList(len, value);
|
||||
List<Integer> list1 = getLinkedListOriginOrder(node1);
|
||||
node1 = reverseLinkedList(node1);
|
||||
if (!checkLinkedListReverse(list1, node1)) {
|
||||
System.out.println("Oops1!");
|
||||
}
|
||||
|
||||
Node node2 = generateRandomLinkedList(len, value);
|
||||
List<Integer> list2 = getLinkedListOriginOrder(node2);
|
||||
node2 = testReverseLinkedList(node2);
|
||||
if (!checkLinkedListReverse(list2, node2)) {
|
||||
System.out.println("Oops2!");
|
||||
}
|
||||
|
||||
DoubleNode node3 = generateRandomDoubleList(len, value);
|
||||
List<Integer> list3 = getDoubleListOriginOrder(node3);
|
||||
node3 = reverseDoubleList(node3);
|
||||
if (!checkDoubleListReverse(list3, node3)) {
|
||||
System.out.println("Oops3!");
|
||||
}
|
||||
|
||||
DoubleNode node4 = generateRandomDoubleList(len, value);
|
||||
List<Integer> list4 = getDoubleListOriginOrder(node4);
|
||||
node4 = reverseDoubleList(node4);
|
||||
if (!checkDoubleListReverse(list4, node4)) {
|
||||
System.out.println("Oops4!");
|
||||
}
|
||||
|
||||
}
|
||||
System.out.println("test finish!");
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package class03;
|
||||
|
||||
public class Code02_DeleteGivenValue {
|
||||
|
||||
public static class Node {
|
||||
public int value;
|
||||
public Node next;
|
||||
|
||||
public Node(int data) {
|
||||
this.value = data;
|
||||
}
|
||||
}
|
||||
|
||||
// head = removeValue(head, 2);
|
||||
public static Node removeValue(Node head, int num) {
|
||||
// head来到第一个不需要删的位置
|
||||
while (head != null) {
|
||||
if (head.value != num) {
|
||||
break;
|
||||
}
|
||||
head = head.next;
|
||||
}
|
||||
// 1 ) head == null
|
||||
// 2 ) head != null
|
||||
Node pre = head;
|
||||
Node cur = head;
|
||||
while (cur != null) {
|
||||
if (cur.value == num) {
|
||||
pre.next = cur.next;
|
||||
} else {
|
||||
pre = cur;
|
||||
}
|
||||
cur = cur.next;
|
||||
}
|
||||
return head;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,183 @@
|
||||
package class03;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
import java.util.Stack;
|
||||
|
||||
public class Code03_DoubleEndsQueueToStackAndQueue {
|
||||
|
||||
public static class Node<T> {
|
||||
public T value;
|
||||
public Node<T> last;
|
||||
public Node<T> next;
|
||||
|
||||
public Node(T data) {
|
||||
value = data;
|
||||
}
|
||||
}
|
||||
|
||||
public static class DoubleEndsQueue<T> {
|
||||
public Node<T> head;
|
||||
public Node<T> tail;
|
||||
|
||||
public void addFromHead(T value) {
|
||||
Node<T> cur = new Node<T>(value);
|
||||
if (head == null) {
|
||||
head = cur;
|
||||
tail = cur;
|
||||
} else {
|
||||
cur.next = head;
|
||||
head.last = cur;
|
||||
head = cur;
|
||||
}
|
||||
}
|
||||
|
||||
public void addFromBottom(T value) {
|
||||
Node<T> cur = new Node<T>(value);
|
||||
if (head == null) {
|
||||
head = cur;
|
||||
tail = cur;
|
||||
} else {
|
||||
cur.last = tail;
|
||||
tail.next = cur;
|
||||
tail = cur;
|
||||
}
|
||||
}
|
||||
|
||||
public T popFromHead() {
|
||||
if (head == null) {
|
||||
return null;
|
||||
}
|
||||
Node<T> cur = head;
|
||||
if (head == tail) {
|
||||
head = null;
|
||||
tail = null;
|
||||
} else {
|
||||
head = head.next;
|
||||
cur.next = null;
|
||||
head.last = null;
|
||||
}
|
||||
return cur.value;
|
||||
}
|
||||
|
||||
public T popFromBottom() {
|
||||
if (head == null) {
|
||||
return null;
|
||||
}
|
||||
Node<T> cur = tail;
|
||||
if (head == tail) {
|
||||
head = null;
|
||||
tail = null;
|
||||
} else {
|
||||
tail = tail.last;
|
||||
tail.next = null;
|
||||
cur.last = null;
|
||||
}
|
||||
return cur.value;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return head == null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class MyStack<T> {
|
||||
private DoubleEndsQueue<T> queue;
|
||||
|
||||
public MyStack() {
|
||||
queue = new DoubleEndsQueue<T>();
|
||||
}
|
||||
|
||||
public void push(T value) {
|
||||
queue.addFromHead(value);
|
||||
}
|
||||
|
||||
public T pop() {
|
||||
return queue.popFromHead();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return queue.isEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class MyQueue<T> {
|
||||
private DoubleEndsQueue<T> queue;
|
||||
|
||||
public MyQueue() {
|
||||
queue = new DoubleEndsQueue<T>();
|
||||
}
|
||||
|
||||
public void push(T value) {
|
||||
queue.addFromHead(value);
|
||||
}
|
||||
|
||||
public T poll() {
|
||||
return queue.popFromBottom();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return queue.isEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static boolean isEqual(Integer o1, Integer o2) {
|
||||
if (o1 == null && o2 != null) {
|
||||
return false;
|
||||
}
|
||||
if (o1 != null && o2 == null) {
|
||||
return false;
|
||||
}
|
||||
if (o1 == null && o2 == null) {
|
||||
return true;
|
||||
}
|
||||
return o1.equals(o2);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int oneTestDataNum = 100;
|
||||
int value = 10000;
|
||||
int testTimes = 100000;
|
||||
for (int i = 0; i < testTimes; i++) {
|
||||
MyStack<Integer> myStack = new MyStack<>();
|
||||
MyQueue<Integer> myQueue = new MyQueue<>();
|
||||
Stack<Integer> stack = new Stack<>();
|
||||
Queue<Integer> queue = new LinkedList<>();
|
||||
for (int j = 0; j < oneTestDataNum; j++) {
|
||||
int nums = (int) (Math.random() * value);
|
||||
if (stack.isEmpty()) {
|
||||
myStack.push(nums);
|
||||
stack.push(nums);
|
||||
} else {
|
||||
if (Math.random() < 0.5) {
|
||||
myStack.push(nums);
|
||||
stack.push(nums);
|
||||
} else {
|
||||
if (!isEqual(myStack.pop(), stack.pop())) {
|
||||
System.out.println("oops!");
|
||||
}
|
||||
}
|
||||
}
|
||||
int numq = (int) (Math.random() * value);
|
||||
if (queue.isEmpty()) {
|
||||
myQueue.push(numq);
|
||||
queue.offer(numq);
|
||||
} else {
|
||||
if (Math.random() < 0.5) {
|
||||
myQueue.push(numq);
|
||||
queue.offer(numq);
|
||||
} else {
|
||||
if (!isEqual(myQueue.poll(), queue.poll())) {
|
||||
System.out.println("oops!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println("finish!");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
package class03;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
public class Code05_GetMinStack {
|
||||
|
||||
public static class MyStack1 {
|
||||
private Stack<Integer> stackData;
|
||||
private Stack<Integer> stackMin;
|
||||
|
||||
public MyStack1() {
|
||||
this.stackData = new Stack<Integer>();
|
||||
this.stackMin = new Stack<Integer>();
|
||||
}
|
||||
|
||||
public void push(int newNum) {
|
||||
if (this.stackMin.isEmpty()) {
|
||||
this.stackMin.push(newNum);
|
||||
} else if (newNum <= this.getmin()) {
|
||||
this.stackMin.push(newNum);
|
||||
}
|
||||
this.stackData.push(newNum);
|
||||
}
|
||||
|
||||
public int pop() {
|
||||
if (this.stackData.isEmpty()) {
|
||||
throw new RuntimeException("Your stack is empty.");
|
||||
}
|
||||
int value = this.stackData.pop();
|
||||
if (value == this.getmin()) {
|
||||
this.stackMin.pop();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public int getmin() {
|
||||
if (this.stackMin.isEmpty()) {
|
||||
throw new RuntimeException("Your stack is empty.");
|
||||
}
|
||||
return this.stackMin.peek();
|
||||
}
|
||||
}
|
||||
|
||||
public static class MyStack2 {
|
||||
private Stack<Integer> stackData;
|
||||
private Stack<Integer> stackMin;
|
||||
|
||||
public MyStack2() {
|
||||
this.stackData = new Stack<Integer>();
|
||||
this.stackMin = new Stack<Integer>();
|
||||
}
|
||||
|
||||
public void push(int newNum) {
|
||||
if (this.stackMin.isEmpty()) {
|
||||
this.stackMin.push(newNum);
|
||||
} else if (newNum < this.getmin()) {
|
||||
this.stackMin.push(newNum);
|
||||
} else {
|
||||
int newMin = this.stackMin.peek();
|
||||
this.stackMin.push(newMin);
|
||||
}
|
||||
this.stackData.push(newNum);
|
||||
}
|
||||
|
||||
public int pop() {
|
||||
if (this.stackData.isEmpty()) {
|
||||
throw new RuntimeException("Your stack is empty.");
|
||||
}
|
||||
this.stackMin.pop();
|
||||
return this.stackData.pop();
|
||||
}
|
||||
|
||||
public int getmin() {
|
||||
if (this.stackMin.isEmpty()) {
|
||||
throw new RuntimeException("Your stack is empty.");
|
||||
}
|
||||
return this.stackMin.peek();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
MyStack1 stack1 = new MyStack1();
|
||||
stack1.push(3);
|
||||
System.out.println(stack1.getmin());
|
||||
stack1.push(4);
|
||||
System.out.println(stack1.getmin());
|
||||
stack1.push(1);
|
||||
System.out.println(stack1.getmin());
|
||||
System.out.println(stack1.pop());
|
||||
System.out.println(stack1.getmin());
|
||||
|
||||
System.out.println("=============");
|
||||
|
||||
MyStack1 stack2 = new MyStack1();
|
||||
stack2.push(3);
|
||||
System.out.println(stack2.getmin());
|
||||
stack2.push(4);
|
||||
System.out.println(stack2.getmin());
|
||||
stack2.push(1);
|
||||
System.out.println(stack2.getmin());
|
||||
System.out.println(stack2.pop());
|
||||
System.out.println(stack2.getmin());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package class03;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
public class Code06_TwoStacksImplementQueue {
|
||||
|
||||
public static class TwoStacksQueue {
|
||||
public Stack<Integer> stackPush;
|
||||
public Stack<Integer> stackPop;
|
||||
|
||||
public TwoStacksQueue() {
|
||||
stackPush = new Stack<Integer>();
|
||||
stackPop = new Stack<Integer>();
|
||||
}
|
||||
|
||||
// push栈向pop栈倒入数据
|
||||
private void pushToPop() {
|
||||
if (stackPop.empty()) {
|
||||
while (!stackPush.empty()) {
|
||||
stackPop.push(stackPush.pop());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void add(int pushInt) {
|
||||
stackPush.push(pushInt);
|
||||
pushToPop();
|
||||
}
|
||||
|
||||
public int poll() {
|
||||
if (stackPop.empty() && stackPush.empty()) {
|
||||
throw new RuntimeException("Queue is empty!");
|
||||
}
|
||||
pushToPop();
|
||||
return stackPop.pop();
|
||||
}
|
||||
|
||||
public int peek() {
|
||||
if (stackPop.empty() && stackPush.empty()) {
|
||||
throw new RuntimeException("Queue is empty!");
|
||||
}
|
||||
pushToPop();
|
||||
return stackPop.peek();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
TwoStacksQueue test = new TwoStacksQueue();
|
||||
test.add(1);
|
||||
test.add(2);
|
||||
test.add(3);
|
||||
System.out.println(test.peek());
|
||||
System.out.println(test.poll());
|
||||
System.out.println(test.peek());
|
||||
System.out.println(test.poll());
|
||||
System.out.println(test.peek());
|
||||
System.out.println(test.poll());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
package class03;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
import java.util.Stack;
|
||||
|
||||
public class Code07_TwoQueueImplementStack {
|
||||
|
||||
public static class TwoQueueStack<T> {
|
||||
public Queue<T> queue;
|
||||
public Queue<T> help;
|
||||
|
||||
public TwoQueueStack() {
|
||||
queue = new LinkedList<>();
|
||||
help = new LinkedList<>();
|
||||
}
|
||||
|
||||
public void push(T value) {
|
||||
queue.offer(value);
|
||||
}
|
||||
|
||||
public T poll() {
|
||||
while (queue.size() > 1) {
|
||||
help.offer(queue.poll());
|
||||
}
|
||||
T ans = queue.poll();
|
||||
Queue<T> tmp = queue;
|
||||
queue = help;
|
||||
help = tmp;
|
||||
return ans;
|
||||
}
|
||||
|
||||
public T peek() {
|
||||
while (queue.size() > 1) {
|
||||
help.offer(queue.poll());
|
||||
}
|
||||
T ans = queue.poll();
|
||||
help.offer(ans);
|
||||
Queue<T> tmp = queue;
|
||||
queue = help;
|
||||
help = tmp;
|
||||
return ans;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return queue.isEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println("test begin");
|
||||
TwoQueueStack<Integer> myStack = new TwoQueueStack<>();
|
||||
Stack<Integer> test = new Stack<>();
|
||||
int testTime = 1000000;
|
||||
int max = 1000000;
|
||||
for (int i = 0; i < testTime; i++) {
|
||||
if (myStack.isEmpty()) {
|
||||
if (!test.isEmpty()) {
|
||||
System.out.println("Oops");
|
||||
}
|
||||
int num = (int) (Math.random() * max);
|
||||
myStack.push(num);
|
||||
test.push(num);
|
||||
} else {
|
||||
if (Math.random() < 0.25) {
|
||||
int num = (int) (Math.random() * max);
|
||||
myStack.push(num);
|
||||
test.push(num);
|
||||
} else if (Math.random() < 0.5) {
|
||||
if (!myStack.peek().equals(test.peek())) {
|
||||
System.out.println("Oops");
|
||||
}
|
||||
} else if (Math.random() < 0.75) {
|
||||
if (!myStack.poll().equals(test.pop())) {
|
||||
System.out.println("Oops");
|
||||
}
|
||||
} else {
|
||||
if (myStack.isEmpty() != test.isEmpty()) {
|
||||
System.out.println("Oops");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("test finish!");
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,135 @@
|
||||
package class04;
|
||||
|
||||
// 本题测试链接 : https://leetcode.com/problems/reverse-pairs/
|
||||
public class Code04_BiggerThanRightTwice {
|
||||
|
||||
public static int reversePairs(int[] arr) {
|
||||
if (arr == null || arr.length < 2) {
|
||||
return 0;
|
||||
}
|
||||
return process(arr, 0, arr.length - 1);
|
||||
}
|
||||
|
||||
public static int process(int[] arr, int l, int r) {
|
||||
if (l == r) {
|
||||
return 0;
|
||||
}
|
||||
// l < r
|
||||
int mid = l + ((r - l) >> 1);
|
||||
return process(arr, l, mid) + process(arr, mid + 1, r) + merge(arr, l, mid, r);
|
||||
}
|
||||
|
||||
public static int merge(int[] arr, int L, int m, int r) {
|
||||
// [L....M] [M+1....R]
|
||||
int ans = 0;
|
||||
// 目前囊括进来的数,是从[M+1, windowR)
|
||||
int windowR = m + 1;
|
||||
for (int i = L; i <= m; i++) {
|
||||
while (windowR <= r && (long) arr[i] > (long) arr[windowR] * 2) {
|
||||
windowR++;
|
||||
}
|
||||
ans += windowR - m - 1;
|
||||
}
|
||||
int[] help = new int[r - L + 1];
|
||||
int i = 0;
|
||||
int p1 = L;
|
||||
int p2 = m + 1;
|
||||
while (p1 <= m && p2 <= r) {
|
||||
help[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
|
||||
}
|
||||
while (p1 <= m) {
|
||||
help[i++] = arr[p1++];
|
||||
}
|
||||
while (p2 <= r) {
|
||||
help[i++] = arr[p2++];
|
||||
}
|
||||
for (i = 0; i < help.length; i++) {
|
||||
arr[L + i] = help[i];
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
// for test
|
||||
public static int comparator(int[] arr) {
|
||||
int ans = 0;
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
for (int j = i + 1; j < arr.length; j++) {
|
||||
if (arr[i] > (arr[j] << 1)) {
|
||||
ans++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
// for test
|
||||
public static int[] generateRandomArray(int maxSize, int maxValue) {
|
||||
int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) ((maxValue + 1) * Math.random());
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
// for test
|
||||
public static int[] copyArray(int[] arr) {
|
||||
if (arr == null) {
|
||||
return null;
|
||||
}
|
||||
int[] res = new int[arr.length];
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
res[i] = arr[i];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// for test
|
||||
public static boolean isEqual(int[] arr1, int[] arr2) {
|
||||
if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {
|
||||
return false;
|
||||
}
|
||||
if (arr1 == null && arr2 == null) {
|
||||
return true;
|
||||
}
|
||||
if (arr1.length != arr2.length) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < arr1.length; i++) {
|
||||
if (arr1[i] != arr2[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// for test
|
||||
public static void printArray(int[] arr) {
|
||||
if (arr == null) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
System.out.print(arr[i] + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
// for test
|
||||
public static void main(String[] args) {
|
||||
int testTime = 500000;
|
||||
int maxSize = 100;
|
||||
int maxValue = 100;
|
||||
System.out.println("测试开始");
|
||||
for (int i = 0; i < testTime; i++) {
|
||||
int[] arr1 = generateRandomArray(maxSize, maxValue);
|
||||
int[] arr2 = copyArray(arr1);
|
||||
if (reversePairs(arr1) != comparator(arr2)) {
|
||||
System.out.println("Oops!");
|
||||
printArray(arr1);
|
||||
printArray(arr2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
System.out.println("测试结束");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,195 @@
|
||||
package class05;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
import java.util.Stack;
|
||||
|
||||
public class Code03_QuickSortRecursiveAndUnrecursive {
|
||||
|
||||
// 荷兰国旗问题
|
||||
public static int[] netherlandsFlag(int[] arr, int L, int R) {
|
||||
if (L > R) {
|
||||
return new int[] { -1, -1 };
|
||||
}
|
||||
if (L == R) {
|
||||
return new int[] { L, R };
|
||||
}
|
||||
int less = L - 1;
|
||||
int more = R;
|
||||
int index = L;
|
||||
while (index < more) {
|
||||
if (arr[index] == arr[R]) {
|
||||
index++;
|
||||
} else if (arr[index] < arr[R]) {
|
||||
swap(arr, index++, ++less);
|
||||
} else {
|
||||
swap(arr, index, --more);
|
||||
}
|
||||
}
|
||||
swap(arr, more, R);
|
||||
return new int[] { less + 1, more };
|
||||
}
|
||||
|
||||
public static void swap(int[] arr, int i, int j) {
|
||||
int tmp = arr[i];
|
||||
arr[i] = arr[j];
|
||||
arr[j] = tmp;
|
||||
}
|
||||
|
||||
// 快排递归版本
|
||||
public static void quickSort1(int[] arr) {
|
||||
if (arr == null || arr.length < 2) {
|
||||
return;
|
||||
}
|
||||
process(arr, 0, arr.length - 1);
|
||||
}
|
||||
|
||||
public static void process(int[] arr, int L, int R) {
|
||||
if (L >= R) {
|
||||
return;
|
||||
}
|
||||
swap(arr, L + (int) (Math.random() * (R - L + 1)), R);
|
||||
int[] equalArea = netherlandsFlag(arr, L, R);
|
||||
process(arr, L, equalArea[0] - 1);
|
||||
process(arr, equalArea[1] + 1, R);
|
||||
}
|
||||
|
||||
// 快排非递归版本需要的辅助类
|
||||
// 要处理的是什么范围上的排序
|
||||
public static class Op {
|
||||
public int l;
|
||||
public int r;
|
||||
|
||||
public Op(int left, int right) {
|
||||
l = left;
|
||||
r = right;
|
||||
}
|
||||
}
|
||||
|
||||
// 快排3.0 非递归版本 用栈来执行
|
||||
public static void quickSort2(int[] arr) {
|
||||
if (arr == null || arr.length < 2) {
|
||||
return;
|
||||
}
|
||||
int N = arr.length;
|
||||
swap(arr, (int) (Math.random() * N), N - 1);
|
||||
int[] equalArea = netherlandsFlag(arr, 0, N - 1);
|
||||
int el = equalArea[0];
|
||||
int er = equalArea[1];
|
||||
Stack<Op> stack = new Stack<>();
|
||||
stack.push(new Op(0, el - 1));
|
||||
stack.push(new Op(er + 1, N - 1));
|
||||
while (!stack.isEmpty()) {
|
||||
Op op = stack.pop(); // op.l ... op.r
|
||||
if (op.l < op.r) {
|
||||
swap(arr, op.l + (int) (Math.random() * (op.r - op.l + 1)), op.r);
|
||||
equalArea = netherlandsFlag(arr, op.l, op.r);
|
||||
el = equalArea[0];
|
||||
er = equalArea[1];
|
||||
stack.push(new Op(op.l, el - 1));
|
||||
stack.push(new Op(er + 1, op.r));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 快排3.0 非递归版本 用队列来执行
|
||||
public static void quickSort3(int[] arr) {
|
||||
if (arr == null || arr.length < 2) {
|
||||
return;
|
||||
}
|
||||
int N = arr.length;
|
||||
swap(arr, (int) (Math.random() * N), N - 1);
|
||||
int[] equalArea = netherlandsFlag(arr, 0, N - 1);
|
||||
int el = equalArea[0];
|
||||
int er = equalArea[1];
|
||||
Queue<Op> queue = new LinkedList<>();
|
||||
queue.offer(new Op(0, el - 1));
|
||||
queue.offer(new Op(er + 1, N - 1));
|
||||
while (!queue.isEmpty()) {
|
||||
Op op = queue.poll();
|
||||
if (op.l < op.r) {
|
||||
swap(arr, op.l + (int) (Math.random() * (op.r - op.l + 1)), op.r);
|
||||
equalArea = netherlandsFlag(arr, op.l, op.r);
|
||||
el = equalArea[0];
|
||||
er = equalArea[1];
|
||||
queue.offer(new Op(op.l, el - 1));
|
||||
queue.offer(new Op(er + 1, op.r));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 生成随机数组(用于测试)
|
||||
public static int[] generateRandomArray(int maxSize, int maxValue) {
|
||||
int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
// 拷贝数组(用于测试)
|
||||
public static int[] copyArray(int[] arr) {
|
||||
if (arr == null) {
|
||||
return null;
|
||||
}
|
||||
int[] res = new int[arr.length];
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
res[i] = arr[i];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// 对比两个数组(用于测试)
|
||||
public static boolean isEqual(int[] arr1, int[] arr2) {
|
||||
if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {
|
||||
return false;
|
||||
}
|
||||
if (arr1 == null && arr2 == null) {
|
||||
return true;
|
||||
}
|
||||
if (arr1.length != arr2.length) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < arr1.length; i++) {
|
||||
if (arr1[i] != arr2[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// 打印数组(用于测试)
|
||||
public static void printArray(int[] arr) {
|
||||
if (arr == null) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
System.out.print(arr[i] + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
// 跑大样本随机测试(对数器)
|
||||
public static void main(String[] args) {
|
||||
int testTime = 500000;
|
||||
int maxSize = 100;
|
||||
int maxValue = 100;
|
||||
boolean succeed = true;
|
||||
System.out.println("test begin");
|
||||
for (int i = 0; i < testTime; i++) {
|
||||
int[] arr1 = generateRandomArray(maxSize, maxValue);
|
||||
int[] arr2 = copyArray(arr1);
|
||||
int[] arr3 = copyArray(arr1);
|
||||
quickSort1(arr1);
|
||||
quickSort2(arr2);
|
||||
quickSort3(arr3);
|
||||
if (!isEqual(arr1, arr2) || !isEqual(arr1, arr3)) {
|
||||
succeed = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
System.out.println("test end");
|
||||
System.out.println("测试" + testTime + "组是否全部通过:" + (succeed ? "是" : "否"));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package class07;
|
||||
|
||||
public class Inner<T> {
|
||||
public T value;
|
||||
|
||||
public Inner(T v) {
|
||||
value = v;
|
||||
}
|
||||
}
|
@ -0,0 +1,111 @@
|
||||
package class08;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class Code03_CountSort {
|
||||
|
||||
// only for 0~200 value
|
||||
public static void countSort(int[] arr) {
|
||||
if (arr == null || arr.length < 2) {
|
||||
return;
|
||||
}
|
||||
int max = Integer.MIN_VALUE;
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
max = Math.max(max, arr[i]);
|
||||
}
|
||||
int[] bucket = new int[max + 1];
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
bucket[arr[i]]++;
|
||||
}
|
||||
int i = 0;
|
||||
for (int j = 0; j < bucket.length; j++) {
|
||||
while (bucket[j]-- > 0) {
|
||||
arr[i++] = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// for test
|
||||
public static void comparator(int[] arr) {
|
||||
Arrays.sort(arr);
|
||||
}
|
||||
|
||||
// for test
|
||||
public static int[] generateRandomArray(int maxSize, int maxValue) {
|
||||
int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
arr[i] = (int) ((maxValue + 1) * Math.random());
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
// for test
|
||||
public static int[] copyArray(int[] arr) {
|
||||
if (arr == null) {
|
||||
return null;
|
||||
}
|
||||
int[] res = new int[arr.length];
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
res[i] = arr[i];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// for test
|
||||
public static boolean isEqual(int[] arr1, int[] arr2) {
|
||||
if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {
|
||||
return false;
|
||||
}
|
||||
if (arr1 == null && arr2 == null) {
|
||||
return true;
|
||||
}
|
||||
if (arr1.length != arr2.length) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < arr1.length; i++) {
|
||||
if (arr1[i] != arr2[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// for test
|
||||
public static void printArray(int[] arr) {
|
||||
if (arr == null) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
System.out.print(arr[i] + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
// for test
|
||||
public static void main(String[] args) {
|
||||
int testTime = 500000;
|
||||
int maxSize = 100;
|
||||
int maxValue = 150;
|
||||
boolean succeed = true;
|
||||
for (int i = 0; i < testTime; i++) {
|
||||
int[] arr1 = generateRandomArray(maxSize, maxValue);
|
||||
int[] arr2 = copyArray(arr1);
|
||||
countSort(arr1);
|
||||
comparator(arr2);
|
||||
if (!isEqual(arr1, arr2)) {
|
||||
succeed = false;
|
||||
printArray(arr1);
|
||||
printArray(arr2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
System.out.println(succeed ? "Nice!" : "Fucking fucked!");
|
||||
|
||||
int[] arr = generateRandomArray(maxSize, maxValue);
|
||||
printArray(arr);
|
||||
countSort(arr);
|
||||
printArray(arr);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,148 @@
|
||||
package class08;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class Code04_RadixSort {
|
||||
|
||||
// only for no-negative value
|
||||
public static void radixSort(int[] arr) {
|
||||
if (arr == null || arr.length < 2) {
|
||||
return;
|
||||
}
|
||||
radixSort(arr, 0, arr.length - 1, maxbits(arr));
|
||||
}
|
||||
|
||||
public static int maxbits(int[] arr) {
|
||||
int max = Integer.MIN_VALUE;
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
max = Math.max(max, arr[i]);
|
||||
}
|
||||
int res = 0;
|
||||
while (max != 0) {
|
||||
res++;
|
||||
max /= 10;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// arr[L..R]排序 , 最大值的十进制位数digit
|
||||
public static void radixSort(int[] arr, int L, int R, int digit) {
|
||||
final int radix = 10;
|
||||
int i = 0, j = 0;
|
||||
// 有多少个数准备多少个辅助空间
|
||||
int[] help = new int[R - L + 1];
|
||||
for (int d = 1; d <= digit; d++) { // 有多少位就进出几次
|
||||
// 10个空间
|
||||
// count[0] 当前位(d位)是0的数字有多少个
|
||||
// count[1] 当前位(d位)是(0和1)的数字有多少个
|
||||
// count[2] 当前位(d位)是(0、1和2)的数字有多少个
|
||||
// count[i] 当前位(d位)是(0~i)的数字有多少个
|
||||
int[] count = new int[radix]; // count[0..9]
|
||||
for (i = L; i <= R; i++) {
|
||||
// 103 1 3
|
||||
// 209 1 9
|
||||
j = getDigit(arr[i], d);
|
||||
count[j]++;
|
||||
}
|
||||
for (i = 1; i < radix; i++) {
|
||||
count[i] = count[i] + count[i - 1];
|
||||
}
|
||||
for (i = R; i >= L; i--) {
|
||||
j = getDigit(arr[i], d);
|
||||
help[count[j] - 1] = arr[i];
|
||||
count[j]--;
|
||||
}
|
||||
for (i = L, j = 0; i <= R; i++, j++) {
|
||||
arr[i] = help[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int getDigit(int x, int d) {
|
||||
return ((x / ((int) Math.pow(10, d - 1))) % 10);
|
||||
}
|
||||
|
||||
// for test
|
||||
public static void comparator(int[] arr) {
|
||||
Arrays.sort(arr);
|
||||
}
|
||||
|
||||
// for test
|
||||
public static int[] generateRandomArray(int maxSize, int maxValue) {
|
||||
int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
arr[i] = (int) ((maxValue + 1) * Math.random());
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
// for test
|
||||
public static int[] copyArray(int[] arr) {
|
||||
if (arr == null) {
|
||||
return null;
|
||||
}
|
||||
int[] res = new int[arr.length];
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
res[i] = arr[i];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// for test
|
||||
public static boolean isEqual(int[] arr1, int[] arr2) {
|
||||
if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {
|
||||
return false;
|
||||
}
|
||||
if (arr1 == null && arr2 == null) {
|
||||
return true;
|
||||
}
|
||||
if (arr1.length != arr2.length) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < arr1.length; i++) {
|
||||
if (arr1[i] != arr2[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// for test
|
||||
public static void printArray(int[] arr) {
|
||||
if (arr == null) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
System.out.print(arr[i] + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
// for test
|
||||
public static void main(String[] args) {
|
||||
int testTime = 500000;
|
||||
int maxSize = 100;
|
||||
int maxValue = 100000;
|
||||
boolean succeed = true;
|
||||
for (int i = 0; i < testTime; i++) {
|
||||
int[] arr1 = generateRandomArray(maxSize, maxValue);
|
||||
int[] arr2 = copyArray(arr1);
|
||||
radixSort(arr1);
|
||||
comparator(arr2);
|
||||
if (!isEqual(arr1, arr2)) {
|
||||
succeed = false;
|
||||
printArray(arr1);
|
||||
printArray(arr2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
System.out.println(succeed ? "Nice!" : "Fucking fucked!");
|
||||
|
||||
int[] arr = generateRandomArray(maxSize, maxValue);
|
||||
printArray(arr);
|
||||
radixSort(arr);
|
||||
printArray(arr);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,204 @@
|
||||
package class09;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
public class Code02_IsPalindromeList {
|
||||
|
||||
public static class Node {
|
||||
public int value;
|
||||
public Node next;
|
||||
|
||||
public Node(int data) {
|
||||
this.value = data;
|
||||
}
|
||||
}
|
||||
|
||||
// need n extra space
|
||||
public static boolean isPalindrome1(Node head) {
|
||||
Stack<Node> stack = new Stack<Node>();
|
||||
Node cur = head;
|
||||
while (cur != null) {
|
||||
stack.push(cur);
|
||||
cur = cur.next;
|
||||
}
|
||||
while (head != null) {
|
||||
if (head.value != stack.pop().value) {
|
||||
return false;
|
||||
}
|
||||
head = head.next;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// need n/2 extra space
|
||||
public static boolean isPalindrome2(Node head) {
|
||||
if (head == null || head.next == null) {
|
||||
return true;
|
||||
}
|
||||
Node right = head.next;
|
||||
Node cur = head;
|
||||
while (cur.next != null && cur.next.next != null) {
|
||||
right = right.next;
|
||||
cur = cur.next.next;
|
||||
}
|
||||
Stack<Node> stack = new Stack<Node>();
|
||||
while (right != null) {
|
||||
stack.push(right);
|
||||
right = right.next;
|
||||
}
|
||||
while (!stack.isEmpty()) {
|
||||
if (head.value != stack.pop().value) {
|
||||
return false;
|
||||
}
|
||||
head = head.next;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// need O(1) extra space
|
||||
public static boolean isPalindrome3(Node head) {
|
||||
if (head == null || head.next == null) {
|
||||
return true;
|
||||
}
|
||||
Node n1 = head;
|
||||
Node n2 = head;
|
||||
while (n2.next != null && n2.next.next != null) { // find mid node
|
||||
n1 = n1.next; // n1 -> mid
|
||||
n2 = n2.next.next; // n2 -> end
|
||||
}
|
||||
// n1 中点
|
||||
|
||||
|
||||
n2 = n1.next; // n2 -> right part first node
|
||||
n1.next = null; // mid.next -> null
|
||||
Node n3 = null;
|
||||
while (n2 != null) { // right part convert
|
||||
n3 = n2.next; // n3 -> save next node
|
||||
n2.next = n1; // next of right node convert
|
||||
n1 = n2; // n1 move
|
||||
n2 = n3; // n2 move
|
||||
}
|
||||
n3 = n1; // n3 -> save last node
|
||||
n2 = head;// n2 -> left first node
|
||||
boolean res = true;
|
||||
while (n1 != null && n2 != null) { // check palindrome
|
||||
if (n1.value != n2.value) {
|
||||
res = false;
|
||||
break;
|
||||
}
|
||||
n1 = n1.next; // left to mid
|
||||
n2 = n2.next; // right to mid
|
||||
}
|
||||
n1 = n3.next;
|
||||
n3.next = null;
|
||||
while (n1 != null) { // recover list
|
||||
n2 = n1.next;
|
||||
n1.next = n3;
|
||||
n3 = n1;
|
||||
n1 = n2;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public static void printLinkedList(Node node) {
|
||||
System.out.print("Linked List: ");
|
||||
while (node != null) {
|
||||
System.out.print(node.value + " ");
|
||||
node = node.next;
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
Node head = null;
|
||||
printLinkedList(head);
|
||||
System.out.print(isPalindrome1(head) + " | ");
|
||||
System.out.print(isPalindrome2(head) + " | ");
|
||||
System.out.println(isPalindrome3(head) + " | ");
|
||||
printLinkedList(head);
|
||||
System.out.println("=========================");
|
||||
|
||||
head = new Node(1);
|
||||
printLinkedList(head);
|
||||
System.out.print(isPalindrome1(head) + " | ");
|
||||
System.out.print(isPalindrome2(head) + " | ");
|
||||
System.out.println(isPalindrome3(head) + " | ");
|
||||
printLinkedList(head);
|
||||
System.out.println("=========================");
|
||||
|
||||
head = new Node(1);
|
||||
head.next = new Node(2);
|
||||
printLinkedList(head);
|
||||
System.out.print(isPalindrome1(head) + " | ");
|
||||
System.out.print(isPalindrome2(head) + " | ");
|
||||
System.out.println(isPalindrome3(head) + " | ");
|
||||
printLinkedList(head);
|
||||
System.out.println("=========================");
|
||||
|
||||
head = new Node(1);
|
||||
head.next = new Node(1);
|
||||
printLinkedList(head);
|
||||
System.out.print(isPalindrome1(head) + " | ");
|
||||
System.out.print(isPalindrome2(head) + " | ");
|
||||
System.out.println(isPalindrome3(head) + " | ");
|
||||
printLinkedList(head);
|
||||
System.out.println("=========================");
|
||||
|
||||
head = new Node(1);
|
||||
head.next = new Node(2);
|
||||
head.next.next = new Node(3);
|
||||
printLinkedList(head);
|
||||
System.out.print(isPalindrome1(head) + " | ");
|
||||
System.out.print(isPalindrome2(head) + " | ");
|
||||
System.out.println(isPalindrome3(head) + " | ");
|
||||
printLinkedList(head);
|
||||
System.out.println("=========================");
|
||||
|
||||
head = new Node(1);
|
||||
head.next = new Node(2);
|
||||
head.next.next = new Node(1);
|
||||
printLinkedList(head);
|
||||
System.out.print(isPalindrome1(head) + " | ");
|
||||
System.out.print(isPalindrome2(head) + " | ");
|
||||
System.out.println(isPalindrome3(head) + " | ");
|
||||
printLinkedList(head);
|
||||
System.out.println("=========================");
|
||||
|
||||
head = new Node(1);
|
||||
head.next = new Node(2);
|
||||
head.next.next = new Node(3);
|
||||
head.next.next.next = new Node(1);
|
||||
printLinkedList(head);
|
||||
System.out.print(isPalindrome1(head) + " | ");
|
||||
System.out.print(isPalindrome2(head) + " | ");
|
||||
System.out.println(isPalindrome3(head) + " | ");
|
||||
printLinkedList(head);
|
||||
System.out.println("=========================");
|
||||
|
||||
head = new Node(1);
|
||||
head.next = new Node(2);
|
||||
head.next.next = new Node(2);
|
||||
head.next.next.next = new Node(1);
|
||||
printLinkedList(head);
|
||||
System.out.print(isPalindrome1(head) + " | ");
|
||||
System.out.print(isPalindrome2(head) + " | ");
|
||||
System.out.println(isPalindrome3(head) + " | ");
|
||||
printLinkedList(head);
|
||||
System.out.println("=========================");
|
||||
|
||||
head = new Node(1);
|
||||
head.next = new Node(2);
|
||||
head.next.next = new Node(3);
|
||||
head.next.next.next = new Node(2);
|
||||
head.next.next.next.next = new Node(1);
|
||||
printLinkedList(head);
|
||||
System.out.print(isPalindrome1(head) + " | ");
|
||||
System.out.print(isPalindrome2(head) + " | ");
|
||||
System.out.println(isPalindrome3(head) + " | ");
|
||||
printLinkedList(head);
|
||||
System.out.println("=========================");
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
package class10;
|
||||
|
||||
public class Code02_RecursiveTraversalBT {
|
||||
|
||||
public static class Node {
|
||||
public int value;
|
||||
public Node left;
|
||||
public Node right;
|
||||
|
||||
public Node(int v) {
|
||||
value = v;
|
||||
}
|
||||
}
|
||||
|
||||
public static void f(Node head) {
|
||||
if (head == null) {
|
||||
return;
|
||||
}
|
||||
// 1
|
||||
f(head.left);
|
||||
// 2
|
||||
f(head.right);
|
||||
// 3
|
||||
}
|
||||
|
||||
// 先序打印所有节点
|
||||
public static void pre(Node head) {
|
||||
if (head == null) {
|
||||
return;
|
||||
}
|
||||
System.out.println(head.value);
|
||||
pre(head.left);
|
||||
pre(head.right);
|
||||
}
|
||||
|
||||
public static void in(Node head) {
|
||||
if (head == null) {
|
||||
return;
|
||||
}
|
||||
in(head.left);
|
||||
System.out.println(head.value);
|
||||
in(head.right);
|
||||
}
|
||||
|
||||
public static void pos(Node head) {
|
||||
if (head == null) {
|
||||
return;
|
||||
}
|
||||
pos(head.left);
|
||||
pos(head.right);
|
||||
System.out.println(head.value);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Node head = new Node(1);
|
||||
head.left = new Node(2);
|
||||
head.right = new Node(3);
|
||||
head.left.left = new Node(4);
|
||||
head.left.right = new Node(5);
|
||||
head.right.left = new Node(6);
|
||||
head.right.right = new Node(7);
|
||||
|
||||
pre(head);
|
||||
System.out.println("========");
|
||||
in(head);
|
||||
System.out.println("========");
|
||||
pos(head);
|
||||
System.out.println("========");
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,118 @@
|
||||
package class10;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
public class Code03_UnRecursiveTraversalBT {
|
||||
|
||||
public static class Node {
|
||||
public int value;
|
||||
public Node left;
|
||||
public Node right;
|
||||
|
||||
public Node(int v) {
|
||||
value = v;
|
||||
}
|
||||
}
|
||||
|
||||
public static void pre(Node head) {
|
||||
System.out.print("pre-order: ");
|
||||
if (head != null) {
|
||||
Stack<Node> stack = new Stack<Node>();
|
||||
stack.add(head);
|
||||
while (!stack.isEmpty()) {
|
||||
head = stack.pop();
|
||||
System.out.print(head.value + " ");
|
||||
if (head.right != null) {
|
||||
stack.push(head.right);
|
||||
}
|
||||
if (head.left != null) {
|
||||
stack.push(head.left);
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
public static void in(Node cur) {
|
||||
System.out.print("in-order: ");
|
||||
if (cur != null) {
|
||||
Stack<Node> stack = new Stack<Node>();
|
||||
while (!stack.isEmpty() || cur != null) {
|
||||
if (cur != null) {
|
||||
stack.push(cur);
|
||||
cur = cur.left;
|
||||
} else {
|
||||
cur = stack.pop();
|
||||
System.out.print(cur.value + " ");
|
||||
cur = cur.right;
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
public static void pos1(Node head) {
|
||||
System.out.print("pos-order: ");
|
||||
if (head != null) {
|
||||
Stack<Node> s1 = new Stack<Node>();
|
||||
Stack<Node> s2 = new Stack<Node>();
|
||||
s1.push(head);
|
||||
while (!s1.isEmpty()) {
|
||||
head = s1.pop(); // 头 右 左
|
||||
s2.push(head);
|
||||
if (head.left != null) {
|
||||
s1.push(head.left);
|
||||
}
|
||||
if (head.right != null) {
|
||||
s1.push(head.right);
|
||||
}
|
||||
}
|
||||
// 左 右 头
|
||||
while (!s2.isEmpty()) {
|
||||
System.out.print(s2.pop().value + " ");
|
||||
}
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
public static void pos2(Node h) {
|
||||
System.out.print("pos-order: ");
|
||||
if (h != null) {
|
||||
Stack<Node> stack = new Stack<Node>();
|
||||
stack.push(h);
|
||||
Node c = null;
|
||||
while (!stack.isEmpty()) {
|
||||
c = stack.peek();
|
||||
if (c.left != null && h != c.left && h != c.right) {
|
||||
stack.push(c.left);
|
||||
} else if (c.right != null && h != c.right) {
|
||||
stack.push(c.right);
|
||||
} else {
|
||||
System.out.print(stack.pop().value + " ");
|
||||
h = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Node head = new Node(1);
|
||||
head.left = new Node(2);
|
||||
head.right = new Node(3);
|
||||
head.left.left = new Node(4);
|
||||
head.left.right = new Node(5);
|
||||
head.right.left = new Node(6);
|
||||
head.right.right = new Node(7);
|
||||
|
||||
pre(head);
|
||||
System.out.println("========");
|
||||
in(head);
|
||||
System.out.println("========");
|
||||
pos1(head);
|
||||
System.out.println("========");
|
||||
pos2(head);
|
||||
System.out.println("========");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package class11;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
public class Code01_LevelTraversalBT {
|
||||
|
||||
public static class Node {
|
||||
public int value;
|
||||
public Node left;
|
||||
public Node right;
|
||||
|
||||
public Node(int v) {
|
||||
value = v;
|
||||
}
|
||||
}
|
||||
|
||||
public static void level(Node head) {
|
||||
if (head == null) {
|
||||
return;
|
||||
}
|
||||
Queue<Node> queue = new LinkedList<>();
|
||||
queue.add(head);
|
||||
while (!queue.isEmpty()) {
|
||||
Node cur = queue.poll();
|
||||
System.out.println(cur.value);
|
||||
if (cur.left != null) {
|
||||
queue.add(cur.left);
|
||||
}
|
||||
if (cur.right != null) {
|
||||
queue.add(cur.right);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Node head = new Node(1);
|
||||
head.left = new Node(2);
|
||||
head.right = new Node(3);
|
||||
head.left.left = new Node(4);
|
||||
head.left.right = new Node(5);
|
||||
head.right.left = new Node(6);
|
||||
head.right.right = new Node(7);
|
||||
|
||||
level(head);
|
||||
System.out.println("========");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
package class11;
|
||||
|
||||
public class Code04_PrintBinaryTree {
|
||||
|
||||
public static class Node {
|
||||
public int value;
|
||||
public Node left;
|
||||
public Node right;
|
||||
|
||||
public Node(int data) {
|
||||
this.value = data;
|
||||
}
|
||||
}
|
||||
|
||||
public static void printTree(Node head) {
|
||||
System.out.println("Binary Tree:");
|
||||
printInOrder(head, 0, "H", 17);
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
public static void printInOrder(Node head, int height, String to, int len) {
|
||||
if (head == null) {
|
||||
return;
|
||||
}
|
||||
printInOrder(head.right, height + 1, "v", len);
|
||||
String val = to + head.value + 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 void main(String[] args) {
|
||||
Node head = new Node(1);
|
||||
head.left = new Node(-222222222);
|
||||
head.right = new Node(3);
|
||||
head.left.left = new Node(Integer.MIN_VALUE);
|
||||
head.right.left = new Node(55555555);
|
||||
head.right.right = new Node(66);
|
||||
head.left.left.right = new Node(777);
|
||||
printTree(head);
|
||||
|
||||
head = new Node(1);
|
||||
head.left = new Node(2);
|
||||
head.right = new Node(3);
|
||||
head.left.left = new Node(4);
|
||||
head.right.left = new Node(5);
|
||||
head.right.right = new Node(6);
|
||||
head.left.left.right = new Node(7);
|
||||
printTree(head);
|
||||
|
||||
head = new Node(1);
|
||||
head.left = new Node(1);
|
||||
head.right = new Node(1);
|
||||
head.left.left = new Node(1);
|
||||
head.right.left = new Node(1);
|
||||
head.right.right = new Node(1);
|
||||
head.left.left.right = new Node(1);
|
||||
printTree(head);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
package class11;
|
||||
|
||||
public class Code06_SuccessorNode {
|
||||
|
||||
public static class Node {
|
||||
public int value;
|
||||
public Node left;
|
||||
public Node right;
|
||||
public Node parent;
|
||||
|
||||
public Node(int data) {
|
||||
this.value = data;
|
||||
}
|
||||
}
|
||||
|
||||
public static Node getSuccessorNode(Node node) {
|
||||
if (node == null) {
|
||||
return node;
|
||||
}
|
||||
if (node.right != null) {
|
||||
return getLeftMost(node.right);
|
||||
} else { // 无右子树
|
||||
Node parent = node.parent;
|
||||
while (parent != null && parent.right == node) { // 当前节点是其父亲节点右孩子
|
||||
node = parent;
|
||||
parent = node.parent;
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
|
||||
public static Node getLeftMost(Node node) {
|
||||
if (node == null) {
|
||||
return node;
|
||||
}
|
||||
while (node.left != null) {
|
||||
node = node.left;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Node head = new Node(6);
|
||||
head.parent = null;
|
||||
head.left = new Node(3);
|
||||
head.left.parent = head;
|
||||
head.left.left = new Node(1);
|
||||
head.left.left.parent = head.left;
|
||||
head.left.left.right = new Node(2);
|
||||
head.left.left.right.parent = head.left.left;
|
||||
head.left.right = new Node(4);
|
||||
head.left.right.parent = head.left;
|
||||
head.left.right.right = new Node(5);
|
||||
head.left.right.right.parent = head.left.right;
|
||||
head.right = new Node(9);
|
||||
head.right.parent = head;
|
||||
head.right.left = new Node(8);
|
||||
head.right.left.parent = head.right;
|
||||
head.right.left.left = new Node(7);
|
||||
head.right.left.left.parent = head.right.left;
|
||||
head.right.right = new Node(10);
|
||||
head.right.right.parent = head.right;
|
||||
|
||||
Node test = head.left.left;
|
||||
System.out.println(test.value + " next: " + getSuccessorNode(test).value);
|
||||
test = head.left.left.right;
|
||||
System.out.println(test.value + " next: " + getSuccessorNode(test).value);
|
||||
test = head.left;
|
||||
System.out.println(test.value + " next: " + getSuccessorNode(test).value);
|
||||
test = head.left.right;
|
||||
System.out.println(test.value + " next: " + getSuccessorNode(test).value);
|
||||
test = head.left.right.right;
|
||||
System.out.println(test.value + " next: " + getSuccessorNode(test).value);
|
||||
test = head;
|
||||
System.out.println(test.value + " next: " + getSuccessorNode(test).value);
|
||||
test = head.right.left.left;
|
||||
System.out.println(test.value + " next: " + getSuccessorNode(test).value);
|
||||
test = head.right.left;
|
||||
System.out.println(test.value + " next: " + getSuccessorNode(test).value);
|
||||
test = head.right;
|
||||
System.out.println(test.value + " next: " + getSuccessorNode(test).value);
|
||||
test = head.right.right; // 10's next is null
|
||||
System.out.println(test.value + " next: " + getSuccessorNode(test));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,125 @@
|
||||
package class12;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Code02_IsBST {
|
||||
|
||||
public static class Node {
|
||||
public int value;
|
||||
public Node left;
|
||||
public Node right;
|
||||
|
||||
public Node(int data) {
|
||||
this.value = data;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isBST1(Node head) {
|
||||
if (head == null) {
|
||||
return true;
|
||||
}
|
||||
ArrayList<Node> arr = new ArrayList<>();
|
||||
in(head, arr);
|
||||
for (int i = 1; i < arr.size(); i++) {
|
||||
if (arr.get(i).value <= arr.get(i - 1).value) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void in(Node head, ArrayList<Node> arr) {
|
||||
if (head == null) {
|
||||
return;
|
||||
}
|
||||
in(head.left, arr);
|
||||
arr.add(head);
|
||||
in(head.right, arr);
|
||||
}
|
||||
|
||||
public static boolean isBST2(Node head) {
|
||||
if (head == null) {
|
||||
return true;
|
||||
}
|
||||
return process(head).isBST;
|
||||
}
|
||||
|
||||
public static class Info {
|
||||
public boolean isBST;
|
||||
public int max;
|
||||
public int min;
|
||||
|
||||
public Info(boolean i, int ma, int mi) {
|
||||
isBST = i;
|
||||
max = ma;
|
||||
min = mi;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static Info process(Node x) {
|
||||
if (x == null) {
|
||||
return null;
|
||||
}
|
||||
Info leftInfo = process(x.left);
|
||||
Info rightInfo = process(x.right);
|
||||
int max = x.value;
|
||||
// if (leftInfo != null) {
|
||||
// max = Math.max(max, leftInfo.max);
|
||||
// }
|
||||
if (rightInfo != null) {
|
||||
max = Math.max(max, rightInfo.max);
|
||||
}
|
||||
int min = x.value;
|
||||
if (leftInfo != null) {
|
||||
min = Math.min(min, leftInfo.min);
|
||||
}
|
||||
// if (rightInfo != null) {
|
||||
// min = Math.min(min, rightInfo.min);
|
||||
// }
|
||||
boolean isBST = true;
|
||||
if (leftInfo != null && !leftInfo.isBST) {
|
||||
isBST = false;
|
||||
}
|
||||
if (rightInfo != null && !rightInfo.isBST) {
|
||||
isBST = false;
|
||||
}
|
||||
if (leftInfo != null && leftInfo.max >= x.value) {
|
||||
isBST = false;
|
||||
}
|
||||
if (rightInfo != null && rightInfo.min <= x.value) {
|
||||
isBST = false;
|
||||
}
|
||||
return new Info(isBST, max, min);
|
||||
}
|
||||
|
||||
// for test
|
||||
public static Node generateRandomBST(int maxLevel, int maxValue) {
|
||||
return generate(1, maxLevel, maxValue);
|
||||
}
|
||||
|
||||
// for test
|
||||
public static Node generate(int level, int maxLevel, int maxValue) {
|
||||
if (level > maxLevel || Math.random() < 0.5) {
|
||||
return null;
|
||||
}
|
||||
Node head = new Node((int) (Math.random() * maxValue));
|
||||
head.left = generate(level + 1, maxLevel, maxValue);
|
||||
head.right = generate(level + 1, maxLevel, maxValue);
|
||||
return head;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int maxLevel = 4;
|
||||
int maxValue = 100;
|
||||
int testTimes = 1000;
|
||||
for (int i = 0; i < testTimes; i++) {
|
||||
Node head = generateRandomBST(maxLevel, maxValue);
|
||||
if (isBST1(head) != isBST2(head)) {
|
||||
System.out.println("Oops!");
|
||||
}
|
||||
}
|
||||
System.out.println("finish!");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
package class12;
|
||||
|
||||
public class Code03_IsBalanced {
|
||||
|
||||
public static class Node {
|
||||
public int value;
|
||||
public Node left;
|
||||
public Node right;
|
||||
|
||||
public Node(int data) {
|
||||
this.value = data;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isBalanced1(Node head) {
|
||||
boolean[] ans = new boolean[1];
|
||||
ans[0] = true;
|
||||
process1(head, ans);
|
||||
return ans[0];
|
||||
}
|
||||
|
||||
public static int process1(Node head, boolean[] ans) {
|
||||
if (!ans[0] || head == null) {
|
||||
return -1;
|
||||
}
|
||||
int leftHeight = process1(head.left, ans);
|
||||
int rightHeight = process1(head.right, ans);
|
||||
if (Math.abs(leftHeight - rightHeight) > 1) {
|
||||
ans[0] = false;
|
||||
}
|
||||
return Math.max(leftHeight, rightHeight) + 1;
|
||||
}
|
||||
|
||||
public static boolean isBalanced2(Node head) {
|
||||
return process(head).isBalanced;
|
||||
}
|
||||
|
||||
public static class Info{
|
||||
public boolean isBalanced;
|
||||
public int height;
|
||||
|
||||
public Info(boolean i, int h) {
|
||||
isBalanced = i;
|
||||
height = h;
|
||||
}
|
||||
}
|
||||
|
||||
public static Info process(Node x) {
|
||||
if(x == null) {
|
||||
return new Info(true, 0);
|
||||
}
|
||||
Info leftInfo = process(x.left);
|
||||
Info rightInfo = process(x.right);
|
||||
int height = Math.max(leftInfo.height, rightInfo.height) + 1;
|
||||
boolean isBalanced = true;
|
||||
if(!leftInfo.isBalanced) {
|
||||
isBalanced = false;
|
||||
}
|
||||
if(!rightInfo.isBalanced) {
|
||||
isBalanced = false;
|
||||
}
|
||||
if(Math.abs(leftInfo.height - rightInfo.height) > 1) {
|
||||
isBalanced = false;
|
||||
}
|
||||
return new Info(isBalanced, height);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// for test
|
||||
public static Node generateRandomBST(int maxLevel, int maxValue) {
|
||||
return generate(1, maxLevel, maxValue);
|
||||
}
|
||||
|
||||
// for test
|
||||
public static Node generate(int level, int maxLevel, int maxValue) {
|
||||
if (level > maxLevel || Math.random() < 0.5) {
|
||||
return null;
|
||||
}
|
||||
Node head = new Node((int) (Math.random() * maxValue));
|
||||
head.left = generate(level + 1, maxLevel, maxValue);
|
||||
head.right = generate(level + 1, maxLevel, maxValue);
|
||||
return head;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int maxLevel = 5;
|
||||
int maxValue = 100;
|
||||
int testTimes = 1000000;
|
||||
for (int i = 0; i < testTimes; i++) {
|
||||
Node head = generateRandomBST(maxLevel, maxValue);
|
||||
if (isBalanced1(head) != isBalanced2(head)) {
|
||||
System.out.println("Oops!");
|
||||
}
|
||||
}
|
||||
System.out.println("finish!");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,240 @@
|
||||
package class12;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Code05_MaxSubBSTSize {
|
||||
|
||||
public static class Node {
|
||||
public int value;
|
||||
public Node left;
|
||||
public Node right;
|
||||
|
||||
public Node(int data) {
|
||||
this.value = data;
|
||||
}
|
||||
}
|
||||
|
||||
public static int getBSTSize(Node head) {
|
||||
if (head == null) {
|
||||
return 0;
|
||||
}
|
||||
ArrayList<Node> arr = new ArrayList<>();
|
||||
in(head, arr);
|
||||
for (int i = 1; i < arr.size(); i++) {
|
||||
if (arr.get(i).value <= arr.get(i - 1).value) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return arr.size();
|
||||
}
|
||||
|
||||
public static void in(Node head, ArrayList<Node> arr) {
|
||||
if (head == null) {
|
||||
return;
|
||||
}
|
||||
in(head.left, arr);
|
||||
arr.add(head);
|
||||
in(head.right, arr);
|
||||
}
|
||||
|
||||
public static int maxSubBSTSize1(Node head) {
|
||||
if (head == null) {
|
||||
return 0;
|
||||
}
|
||||
int h = getBSTSize(head);
|
||||
if (h != 0) {
|
||||
return h;
|
||||
}
|
||||
return Math.max(maxSubBSTSize1(head.left), maxSubBSTSize1(head.right));
|
||||
}
|
||||
|
||||
// public static int maxSubBSTSize2(Node head) {
|
||||
// if (head == null) {
|
||||
// return 0;
|
||||
// }
|
||||
// return process(head).maxSubBSTSize;
|
||||
// }
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// // 任何子树
|
||||
// public static class Info {
|
||||
// public boolean isAllBST;
|
||||
// public int maxSubBSTSize;
|
||||
// public int min;
|
||||
// public int max;
|
||||
//
|
||||
// public Info(boolean is, int size, int mi, int ma) {
|
||||
// isAllBST = is;
|
||||
// maxSubBSTSize = size;
|
||||
// min = mi;
|
||||
// max = ma;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// public static Info process(Node X) {
|
||||
// if(X == null) {
|
||||
// return null;
|
||||
// }
|
||||
// Info leftInfo = process(X.left);
|
||||
// Info rightInfo = process(X.right);
|
||||
//
|
||||
//
|
||||
//
|
||||
// int min = X.value;
|
||||
// int max = X.value;
|
||||
//
|
||||
// if(leftInfo != null) {
|
||||
// min = Math.min(min, leftInfo.min);
|
||||
// max = Math.max(max, leftInfo.max);
|
||||
// }
|
||||
// if(rightInfo != null) {
|
||||
// min = Math.min(min, rightInfo.min);
|
||||
// max = Math.max(max, rightInfo.max);
|
||||
// }
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// int maxSubBSTSize = 0;
|
||||
// if(leftInfo != null) {
|
||||
// maxSubBSTSize = leftInfo.maxSubBSTSize;
|
||||
// }
|
||||
// if(rightInfo !=null) {
|
||||
// maxSubBSTSize = Math.max(maxSubBSTSize, rightInfo.maxSubBSTSize);
|
||||
// }
|
||||
// boolean isAllBST = false;
|
||||
//
|
||||
//
|
||||
// if(
|
||||
// // 左树整体需要是搜索二叉树
|
||||
// ( leftInfo == null ? true : leftInfo.isAllBST )
|
||||
// &&
|
||||
// ( rightInfo == null ? true : rightInfo.isAllBST )
|
||||
// &&
|
||||
// // 左树最大值<x
|
||||
// (leftInfo == null ? true : leftInfo.max < X.value)
|
||||
// &&
|
||||
// (rightInfo == null ? true : rightInfo.min > X.value)
|
||||
//
|
||||
//
|
||||
// ) {
|
||||
//
|
||||
// maxSubBSTSize =
|
||||
// (leftInfo == null ? 0 : leftInfo.maxSubBSTSize)
|
||||
// +
|
||||
// (rightInfo == null ? 0 : rightInfo.maxSubBSTSize)
|
||||
// +
|
||||
// 1;
|
||||
// isAllBST = true;
|
||||
//
|
||||
//
|
||||
// }
|
||||
// return new Info(isAllBST, maxSubBSTSize, min, max);
|
||||
// }
|
||||
|
||||
public static int maxSubBSTSize2(Node head) {
|
||||
if(head == null) {
|
||||
return 0;
|
||||
}
|
||||
return process(head).maxBSTSubtreeSize;
|
||||
}
|
||||
|
||||
public static class Info {
|
||||
public int maxBSTSubtreeSize;
|
||||
public int allSize;
|
||||
public int max;
|
||||
public int min;
|
||||
|
||||
public Info(int m, int a, int ma, int mi) {
|
||||
maxBSTSubtreeSize = m;
|
||||
allSize = a;
|
||||
max = ma;
|
||||
min = mi;
|
||||
}
|
||||
}
|
||||
|
||||
public static Info process(Node x) {
|
||||
if (x == null) {
|
||||
return null;
|
||||
}
|
||||
Info leftInfo = process(x.left);
|
||||
Info rightInfo = process(x.right);
|
||||
int max = x.value;
|
||||
int min = x.value;
|
||||
int allSize = 1;
|
||||
if (leftInfo != null) {
|
||||
max = Math.max(leftInfo.max, max);
|
||||
min = Math.min(leftInfo.min, min);
|
||||
allSize += leftInfo.allSize;
|
||||
}
|
||||
if (rightInfo != null) {
|
||||
max = Math.max(rightInfo.max, max);
|
||||
min = Math.min(rightInfo.min, min);
|
||||
allSize += rightInfo.allSize;
|
||||
}
|
||||
int p1 = -1;
|
||||
if (leftInfo != null) {
|
||||
p1 = leftInfo.maxBSTSubtreeSize;
|
||||
}
|
||||
int p2 = -1;
|
||||
if (rightInfo != null) {
|
||||
p2 = rightInfo.maxBSTSubtreeSize;
|
||||
}
|
||||
int p3 = -1;
|
||||
boolean leftBST = leftInfo == null ? true : (leftInfo.maxBSTSubtreeSize == leftInfo.allSize);
|
||||
boolean rightBST = rightInfo == null ? true : (rightInfo.maxBSTSubtreeSize == rightInfo.allSize);
|
||||
if (leftBST && rightBST) {
|
||||
boolean leftMaxLessX = leftInfo == null ? true : (leftInfo.max < x.value);
|
||||
boolean rightMinMoreX = rightInfo == null ? true : (x.value < rightInfo.min);
|
||||
if (leftMaxLessX && rightMinMoreX) {
|
||||
int leftSize = leftInfo == null ? 0 : leftInfo.allSize;
|
||||
int rightSize = rightInfo == null ? 0 : rightInfo.allSize;
|
||||
p3 = leftSize + rightSize + 1;
|
||||
}
|
||||
}
|
||||
return new Info(Math.max(p1, Math.max(p2, p3)), allSize, max, min);
|
||||
}
|
||||
|
||||
// for test
|
||||
public static Node generateRandomBST(int maxLevel, int maxValue) {
|
||||
return generate(1, maxLevel, maxValue);
|
||||
}
|
||||
|
||||
// for test
|
||||
public static Node generate(int level, int maxLevel, int maxValue) {
|
||||
if (level > maxLevel || Math.random() < 0.5) {
|
||||
return null;
|
||||
}
|
||||
Node head = new Node((int) (Math.random() * maxValue));
|
||||
head.left = generate(level + 1, maxLevel, maxValue);
|
||||
head.right = generate(level + 1, maxLevel, maxValue);
|
||||
return head;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int maxLevel = 4;
|
||||
int maxValue = 100;
|
||||
int testTimes = 1000000;
|
||||
for (int i = 0; i < testTimes; i++) {
|
||||
Node head = generateRandomBST(maxLevel, maxValue);
|
||||
if (maxSubBSTSize1(head) != maxSubBSTSize2(head)) {
|
||||
System.out.println("Oops!");
|
||||
}
|
||||
}
|
||||
System.out.println("finish!");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,180 @@
|
||||
package class12;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class Code06_MaxDistance {
|
||||
|
||||
public static class Node {
|
||||
public int value;
|
||||
public Node left;
|
||||
public Node right;
|
||||
|
||||
public Node(int data) {
|
||||
this.value = data;
|
||||
}
|
||||
}
|
||||
|
||||
public static int maxDistance1(Node head) {
|
||||
if (head == null) {
|
||||
return 0;
|
||||
}
|
||||
ArrayList<Node> arr = getPrelist(head);
|
||||
HashMap<Node, Node> parentMap = getParentMap(head);
|
||||
int max = 0;
|
||||
for (int i = 0; i < arr.size(); i++) {
|
||||
for (int j = i; j < arr.size(); j++) {
|
||||
max = Math.max(max, distance(parentMap, arr.get(i), arr.get(j)));
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
public static ArrayList<Node> getPrelist(Node head) {
|
||||
ArrayList<Node> arr = new ArrayList<>();
|
||||
fillPrelist(head, arr);
|
||||
return arr;
|
||||
}
|
||||
|
||||
public static void fillPrelist(Node head, ArrayList<Node> arr) {
|
||||
if (head == null) {
|
||||
return;
|
||||
}
|
||||
arr.add(head);
|
||||
fillPrelist(head.left, arr);
|
||||
fillPrelist(head.right, arr);
|
||||
}
|
||||
|
||||
public static HashMap<Node, Node> getParentMap(Node head) {
|
||||
HashMap<Node, Node> map = new HashMap<>();
|
||||
map.put(head, null);
|
||||
fillParentMap(head, map);
|
||||
return map;
|
||||
}
|
||||
|
||||
public static void fillParentMap(Node head, HashMap<Node, Node> parentMap) {
|
||||
if (head.left != null) {
|
||||
parentMap.put(head.left, head);
|
||||
fillParentMap(head.left, parentMap);
|
||||
}
|
||||
if (head.right != null) {
|
||||
parentMap.put(head.right, head);
|
||||
fillParentMap(head.right, parentMap);
|
||||
}
|
||||
}
|
||||
|
||||
public static int distance(HashMap<Node, Node> parentMap, Node o1, Node o2) {
|
||||
HashSet<Node> o1Set = new HashSet<>();
|
||||
Node cur = o1;
|
||||
o1Set.add(cur);
|
||||
while (parentMap.get(cur) != null) {
|
||||
cur = parentMap.get(cur);
|
||||
o1Set.add(cur);
|
||||
}
|
||||
cur = o2;
|
||||
while (!o1Set.contains(cur)) {
|
||||
cur = parentMap.get(cur);
|
||||
}
|
||||
Node lowestAncestor = cur;
|
||||
cur = o1;
|
||||
int distance1 = 1;
|
||||
while (cur != lowestAncestor) {
|
||||
cur = parentMap.get(cur);
|
||||
distance1++;
|
||||
}
|
||||
cur = o2;
|
||||
int distance2 = 1;
|
||||
while (cur != lowestAncestor) {
|
||||
cur = parentMap.get(cur);
|
||||
distance2++;
|
||||
}
|
||||
return distance1 + distance2 - 1;
|
||||
}
|
||||
|
||||
// public static int maxDistance2(Node head) {
|
||||
// return process(head).maxDistance;
|
||||
// }
|
||||
//
|
||||
// public static class Info {
|
||||
// public int maxDistance;
|
||||
// public int height;
|
||||
//
|
||||
// public Info(int dis, int h) {
|
||||
// maxDistance = dis;
|
||||
// height = h;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public static Info process(Node X) {
|
||||
// if (X == null) {
|
||||
// return new Info(0, 0);
|
||||
// }
|
||||
// Info leftInfo = process(X.left);
|
||||
// Info rightInfo = process(X.right);
|
||||
// int height = Math.max(leftInfo.height, rightInfo.height) + 1;
|
||||
// int maxDistance = Math.max(
|
||||
// Math.max(leftInfo.maxDistance, rightInfo.maxDistance),
|
||||
// leftInfo.height + rightInfo.height + 1);
|
||||
// return new Info(maxDistance, height);
|
||||
// }
|
||||
|
||||
public static int maxDistance2(Node head) {
|
||||
return process(head).maxDistance;
|
||||
}
|
||||
|
||||
public static class Info {
|
||||
public int maxDistance;
|
||||
public int height;
|
||||
|
||||
public Info(int m, int h) {
|
||||
maxDistance = m;
|
||||
height = h;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static Info process(Node x) {
|
||||
if (x == null) {
|
||||
return new Info(0, 0);
|
||||
}
|
||||
Info leftInfo = process(x.left);
|
||||
Info rightInfo = process(x.right);
|
||||
int height = Math.max(leftInfo.height, rightInfo.height) + 1;
|
||||
int p1 = leftInfo.maxDistance;
|
||||
int p2 = rightInfo.maxDistance;
|
||||
int p3 = leftInfo.height + rightInfo.height + 1;
|
||||
int maxDistance = Math.max(Math.max(p1, p2), p3);
|
||||
return new Info(maxDistance, height);
|
||||
}
|
||||
|
||||
// for test
|
||||
public static Node generateRandomBST(int maxLevel, int maxValue) {
|
||||
return generate(1, maxLevel, maxValue);
|
||||
}
|
||||
|
||||
// for test
|
||||
public static Node generate(int level, int maxLevel, int maxValue) {
|
||||
if (level > maxLevel || Math.random() < 0.5) {
|
||||
return null;
|
||||
}
|
||||
Node head = new Node((int) (Math.random() * maxValue));
|
||||
head.left = generate(level + 1, maxLevel, maxValue);
|
||||
head.right = generate(level + 1, maxLevel, maxValue);
|
||||
return head;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int maxLevel = 4;
|
||||
int maxValue = 100;
|
||||
int testTimes = 1000000;
|
||||
for (int i = 0; i < testTimes; i++) {
|
||||
Node head = generateRandomBST(maxLevel, maxValue);
|
||||
if (maxDistance1(head) != maxDistance2(head)) {
|
||||
System.out.println("Oops!");
|
||||
}
|
||||
}
|
||||
System.out.println("finish!");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,117 @@
|
||||
package class13;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
public class Code01_IsCBT {
|
||||
|
||||
public static class Node {
|
||||
public int value;
|
||||
public Node left;
|
||||
public Node right;
|
||||
|
||||
public Node(int data) {
|
||||
this.value = data;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isCBT1(Node head) {
|
||||
if (head == null) {
|
||||
return true;
|
||||
}
|
||||
LinkedList<Node> queue = new LinkedList<>();
|
||||
// 是否遇到过左右两个孩子不双全的节点
|
||||
boolean leaf = false;
|
||||
Node l = null;
|
||||
Node r = null;
|
||||
queue.add(head);
|
||||
while (!queue.isEmpty()) {
|
||||
head = queue.poll();
|
||||
l = head.left;
|
||||
r = head.right;
|
||||
if (
|
||||
// 如果遇到了不双全的节点之后,又发现当前节点不是叶节点
|
||||
(leaf && (l != null || r != null)) || (l == null && r != null)
|
||||
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if (l != null) {
|
||||
queue.add(l);
|
||||
}
|
||||
if (r != null) {
|
||||
queue.add(r);
|
||||
}
|
||||
if (l == null || r == null) {
|
||||
leaf = true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean isCBT2(Node head) {
|
||||
return process(head).isCBT;
|
||||
}
|
||||
|
||||
public static class Info {
|
||||
public boolean isFull;
|
||||
public boolean isCBT;
|
||||
public int height;
|
||||
|
||||
public Info(boolean full, boolean cbt, int h) {
|
||||
isFull = full;
|
||||
isCBT = cbt;
|
||||
height = h;
|
||||
}
|
||||
}
|
||||
|
||||
public static Info process(Node x) {
|
||||
if (x == null) {
|
||||
return new Info(true, true, 0);
|
||||
}
|
||||
Info leftInfo = process(x.left);
|
||||
Info rightInfo = process(x.right);
|
||||
int height = Math.max(leftInfo.height, rightInfo.height) + 1;
|
||||
boolean isFull = leftInfo.isFull && rightInfo.isFull && leftInfo.height == rightInfo.height;
|
||||
boolean isCBT = false;
|
||||
if (leftInfo.isFull && rightInfo.isFull && leftInfo.height == rightInfo.height) {
|
||||
isCBT = true;
|
||||
} else if (leftInfo.isCBT && rightInfo.isFull && leftInfo.height == rightInfo.height + 1) {
|
||||
isCBT = true;
|
||||
} else if (leftInfo.isFull && rightInfo.isFull && leftInfo.height == rightInfo.height + 1) {
|
||||
isCBT = true;
|
||||
} else if (leftInfo.isFull && rightInfo.isCBT && leftInfo.height == rightInfo.height) {
|
||||
isCBT = true;
|
||||
}
|
||||
return new Info(isFull, isCBT, height);
|
||||
}
|
||||
|
||||
// for test
|
||||
public static Node generateRandomBST(int maxLevel, int maxValue) {
|
||||
return generate(1, maxLevel, maxValue);
|
||||
}
|
||||
|
||||
// for test
|
||||
public static Node generate(int level, int maxLevel, int maxValue) {
|
||||
if (level > maxLevel || Math.random() < 0.5) {
|
||||
return null;
|
||||
}
|
||||
Node head = new Node((int) (Math.random() * maxValue));
|
||||
head.left = generate(level + 1, maxLevel, maxValue);
|
||||
head.right = generate(level + 1, maxLevel, maxValue);
|
||||
return head;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int maxLevel = 5;
|
||||
int maxValue = 100;
|
||||
int testTimes = 1000000;
|
||||
for (int i = 0; i < testTimes; i++) {
|
||||
Node head = generateRandomBST(maxLevel, maxValue);
|
||||
if (isCBT1(head) != isCBT2(head)) {
|
||||
System.out.println("Oops!");
|
||||
}
|
||||
}
|
||||
System.out.println("finish!");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,136 @@
|
||||
package class13;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Code02_MaxSubBSTHead {
|
||||
|
||||
public static class Node {
|
||||
public int value;
|
||||
public Node left;
|
||||
public Node right;
|
||||
|
||||
public Node(int data) {
|
||||
this.value = data;
|
||||
}
|
||||
}
|
||||
|
||||
public static int getBSTSize(Node head) {
|
||||
if (head == null) {
|
||||
return 0;
|
||||
}
|
||||
ArrayList<Node> arr = new ArrayList<>();
|
||||
in(head, arr);
|
||||
for (int i = 1; i < arr.size(); i++) {
|
||||
if (arr.get(i).value <= arr.get(i - 1).value) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return arr.size();
|
||||
}
|
||||
|
||||
public static void in(Node head, ArrayList<Node> arr) {
|
||||
if (head == null) {
|
||||
return;
|
||||
}
|
||||
in(head.left, arr);
|
||||
arr.add(head);
|
||||
in(head.right, arr);
|
||||
}
|
||||
|
||||
public static Node maxSubBSTHead1(Node head) {
|
||||
if (head == null) {
|
||||
return null;
|
||||
}
|
||||
if (getBSTSize(head) != 0) {
|
||||
return head;
|
||||
}
|
||||
Node leftAns = maxSubBSTHead1(head.left);
|
||||
Node rightAns = maxSubBSTHead1(head.right);
|
||||
return getBSTSize(leftAns) >= getBSTSize(rightAns) ? leftAns : rightAns;
|
||||
}
|
||||
|
||||
public static Node maxSubBSTHead2(Node head) {
|
||||
if (head == null) {
|
||||
return null;
|
||||
}
|
||||
return process(head).maxSubBSTHead;
|
||||
}
|
||||
|
||||
// 每一棵子树
|
||||
public static class Info {
|
||||
public Node maxSubBSTHead;
|
||||
public int maxSubBSTSize;
|
||||
public int min;
|
||||
public int max;
|
||||
|
||||
public Info(Node h, int size, int mi, int ma) {
|
||||
maxSubBSTHead = h;
|
||||
maxSubBSTSize = size;
|
||||
min = mi;
|
||||
max = ma;
|
||||
}
|
||||
}
|
||||
|
||||
public static Info process(Node X) {
|
||||
if (X == null) {
|
||||
return null;
|
||||
}
|
||||
Info leftInfo = process(X.left);
|
||||
Info rightInfo = process(X.right);
|
||||
int min = X.value;
|
||||
int max = X.value;
|
||||
Node maxSubBSTHead = null;
|
||||
int maxSubBSTSize = 0;
|
||||
if (leftInfo != null) {
|
||||
min = Math.min(min, leftInfo.min);
|
||||
max = Math.max(max, leftInfo.max);
|
||||
maxSubBSTHead = leftInfo.maxSubBSTHead;
|
||||
maxSubBSTSize = leftInfo.maxSubBSTSize;
|
||||
}
|
||||
if (rightInfo != null) {
|
||||
min = Math.min(min, rightInfo.min);
|
||||
max = Math.max(max, rightInfo.max);
|
||||
if (rightInfo.maxSubBSTSize > maxSubBSTSize) {
|
||||
maxSubBSTHead = rightInfo.maxSubBSTHead;
|
||||
maxSubBSTSize = rightInfo.maxSubBSTSize;
|
||||
}
|
||||
}
|
||||
if ((leftInfo == null ? true : (leftInfo.maxSubBSTHead == X.left && leftInfo.max < X.value))
|
||||
&& (rightInfo == null ? true : (rightInfo.maxSubBSTHead == X.right && rightInfo.min > X.value))) {
|
||||
maxSubBSTHead = X;
|
||||
maxSubBSTSize = (leftInfo == null ? 0 : leftInfo.maxSubBSTSize)
|
||||
+ (rightInfo == null ? 0 : rightInfo.maxSubBSTSize) + 1;
|
||||
}
|
||||
return new Info(maxSubBSTHead, maxSubBSTSize, min, max);
|
||||
}
|
||||
|
||||
// for test
|
||||
public static Node generateRandomBST(int maxLevel, int maxValue) {
|
||||
return generate(1, maxLevel, maxValue);
|
||||
}
|
||||
|
||||
// for test
|
||||
public static Node generate(int level, int maxLevel, int maxValue) {
|
||||
if (level > maxLevel || Math.random() < 0.5) {
|
||||
return null;
|
||||
}
|
||||
Node head = new Node((int) (Math.random() * maxValue));
|
||||
head.left = generate(level + 1, maxLevel, maxValue);
|
||||
head.right = generate(level + 1, maxLevel, maxValue);
|
||||
return head;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int maxLevel = 4;
|
||||
int maxValue = 100;
|
||||
int testTimes = 1000000;
|
||||
for (int i = 0; i < testTimes; i++) {
|
||||
Node head = generateRandomBST(maxLevel, maxValue);
|
||||
if (maxSubBSTHead1(head) != maxSubBSTHead2(head)) {
|
||||
System.out.println("Oops!");
|
||||
}
|
||||
}
|
||||
System.out.println("finish!");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,141 @@
|
||||
package class13;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class Code03_lowestAncestor {
|
||||
|
||||
public static class Node {
|
||||
public int value;
|
||||
public Node left;
|
||||
public Node right;
|
||||
|
||||
public Node(int data) {
|
||||
this.value = data;
|
||||
}
|
||||
}
|
||||
|
||||
public static Node lowestAncestor1(Node head, Node o1, Node o2) {
|
||||
if (head == null) {
|
||||
return null;
|
||||
}
|
||||
// key的父节点是value
|
||||
HashMap<Node, Node> parentMap = new HashMap<>();
|
||||
parentMap.put(head, null);
|
||||
fillParentMap(head, parentMap);
|
||||
HashSet<Node> o1Set = new HashSet<>();
|
||||
Node cur = o1;
|
||||
o1Set.add(cur);
|
||||
while (parentMap.get(cur) != null) {
|
||||
cur = parentMap.get(cur);
|
||||
o1Set.add(cur);
|
||||
}
|
||||
cur = o2;
|
||||
while (!o1Set.contains(cur)) {
|
||||
cur = parentMap.get(cur);
|
||||
}
|
||||
return cur;
|
||||
}
|
||||
|
||||
public static void fillParentMap(Node head, HashMap<Node, Node> parentMap) {
|
||||
if (head.left != null) {
|
||||
parentMap.put(head.left, head);
|
||||
fillParentMap(head.left, parentMap);
|
||||
}
|
||||
if (head.right != null) {
|
||||
parentMap.put(head.right, head);
|
||||
fillParentMap(head.right, parentMap);
|
||||
}
|
||||
}
|
||||
|
||||
public static Node lowestAncestor2(Node head, Node a, Node b) {
|
||||
return process(head, a, b).ans;
|
||||
}
|
||||
|
||||
public static class Info {
|
||||
public boolean findA;
|
||||
public boolean findB;
|
||||
public Node ans;
|
||||
|
||||
public Info(boolean fA, boolean fB, Node an) {
|
||||
findA = fA;
|
||||
findB = fB;
|
||||
ans = an;
|
||||
}
|
||||
}
|
||||
|
||||
public static Info process(Node x, Node a, Node b) {
|
||||
if (x == null) {
|
||||
return new Info(false, false, null);
|
||||
}
|
||||
Info leftInfo = process(x.left, a, b);
|
||||
Info rightInfo = process(x.right, a, b);
|
||||
boolean findA = (x == a) || leftInfo.findA || rightInfo.findA;
|
||||
boolean findB = (x == b) || leftInfo.findB || rightInfo.findB;
|
||||
Node ans = null;
|
||||
if (leftInfo.ans != null) {
|
||||
ans = leftInfo.ans;
|
||||
} else if (rightInfo.ans != null) {
|
||||
ans = rightInfo.ans;
|
||||
} else {
|
||||
if (findA && findB) {
|
||||
ans = x;
|
||||
}
|
||||
}
|
||||
return new Info(findA, findB, ans);
|
||||
}
|
||||
|
||||
// for test
|
||||
public static Node generateRandomBST(int maxLevel, int maxValue) {
|
||||
return generate(1, maxLevel, maxValue);
|
||||
}
|
||||
|
||||
// for test
|
||||
public static Node generate(int level, int maxLevel, int maxValue) {
|
||||
if (level > maxLevel || Math.random() < 0.5) {
|
||||
return null;
|
||||
}
|
||||
Node head = new Node((int) (Math.random() * maxValue));
|
||||
head.left = generate(level + 1, maxLevel, maxValue);
|
||||
head.right = generate(level + 1, maxLevel, maxValue);
|
||||
return head;
|
||||
}
|
||||
|
||||
// for test
|
||||
public static Node pickRandomOne(Node head) {
|
||||
if (head == null) {
|
||||
return null;
|
||||
}
|
||||
ArrayList<Node> arr = new ArrayList<>();
|
||||
fillPrelist(head, arr);
|
||||
int randomIndex = (int) (Math.random() * arr.size());
|
||||
return arr.get(randomIndex);
|
||||
}
|
||||
|
||||
// for test
|
||||
public static void fillPrelist(Node head, ArrayList<Node> arr) {
|
||||
if (head == null) {
|
||||
return;
|
||||
}
|
||||
arr.add(head);
|
||||
fillPrelist(head.left, arr);
|
||||
fillPrelist(head.right, arr);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int maxLevel = 4;
|
||||
int maxValue = 100;
|
||||
int testTimes = 1000000;
|
||||
for (int i = 0; i < testTimes; i++) {
|
||||
Node head = generateRandomBST(maxLevel, maxValue);
|
||||
Node o1 = pickRandomOne(head);
|
||||
Node o2 = pickRandomOne(head);
|
||||
if (lowestAncestor1(head, o1, o2) != lowestAncestor2(head, o1, o2)) {
|
||||
System.out.println("Oops!");
|
||||
}
|
||||
}
|
||||
System.out.println("finish!");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
package class14;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.PriorityQueue;
|
||||
|
||||
public class Code04_IPO {
|
||||
|
||||
// 最多K个项目
|
||||
// W是初始资金
|
||||
// Profits[] Capital[] 一定等长
|
||||
// 返回最终最大的资金
|
||||
public static int findMaximizedCapital(int K, int W, int[] Profits, int[] Capital) {
|
||||
|
||||
PriorityQueue<Program> minCostQ = new PriorityQueue<>(new MinCostComparator());
|
||||
PriorityQueue<Program> maxProfitQ = new PriorityQueue<>(new MaxProfitComparator());
|
||||
for (int i = 0; i < Profits.length; i++) {
|
||||
minCostQ.add(new Program(Profits[i], Capital[i]));
|
||||
}
|
||||
for (int i = 0; i < K; i++) {
|
||||
while (!minCostQ.isEmpty() && minCostQ.peek().c <= W) {
|
||||
maxProfitQ.add(minCostQ.poll());
|
||||
}
|
||||
if (maxProfitQ.isEmpty()) {
|
||||
return W;
|
||||
}
|
||||
W += maxProfitQ.poll().p;
|
||||
}
|
||||
return W;
|
||||
}
|
||||
|
||||
public static class Program {
|
||||
public int p;
|
||||
public int c;
|
||||
|
||||
public Program(int p, int c) {
|
||||
this.p = p;
|
||||
this.c = c;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MinCostComparator implements Comparator<Program> {
|
||||
//花费从小到大
|
||||
@Override
|
||||
public int compare(Program o1, Program o2) {
|
||||
return o1.c - o2.c;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class MaxProfitComparator implements Comparator<Program> {
|
||||
//利润从大到小
|
||||
@Override
|
||||
public int compare(Program o1, Program o2) {
|
||||
return o2.p - o1.p;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
package class14;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class Code05_UnionFind {
|
||||
|
||||
public static class Node<V> {
|
||||
V value;
|
||||
|
||||
public Node(V v) {
|
||||
value = v;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* nodes表用来记录每一个结点
|
||||
* parents表用来记录每一个结点所在集合的代表结点
|
||||
* size表只有当一个结点是代表结点的时候才会有记录
|
||||
* @param <V>
|
||||
*/
|
||||
public static class UnionFind<V> {
|
||||
public HashMap<V, Node<V>> nodes;
|
||||
public HashMap<Node<V>, Node<V>> parents;
|
||||
public HashMap<Node<V>, Integer> sizeMap;
|
||||
|
||||
public UnionFind(List<V> values) {
|
||||
nodes = new HashMap<>();
|
||||
parents = new HashMap<>();
|
||||
sizeMap = new HashMap<>();
|
||||
for (V cur : values) {
|
||||
Node<V> node = new Node<>(cur);
|
||||
nodes.put(cur, node);
|
||||
parents.put(node, node);
|
||||
sizeMap.put(node, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// 给你一个节点,请你往上到不能再往上,把代表返回
|
||||
public Node<V> findFather(Node<V> cur) {
|
||||
Stack<Node<V>> path = new Stack<>();
|
||||
while (cur != parents.get(cur)) {
|
||||
path.push(cur);
|
||||
cur = parents.get(cur);
|
||||
}
|
||||
while (!path.isEmpty()) {
|
||||
parents.put(path.pop(), cur);
|
||||
}
|
||||
return cur;
|
||||
}
|
||||
|
||||
public boolean isSameSet(V a, V b) {
|
||||
return findFather(nodes.get(a)) == findFather(nodes.get(b));
|
||||
}
|
||||
|
||||
public void union(V a, V b) {
|
||||
Node<V> aHead = findFather(nodes.get(a));
|
||||
Node<V> bHead = findFather(nodes.get(b));
|
||||
if (aHead != bHead) {
|
||||
int aSetSize = sizeMap.get(aHead);
|
||||
int bSetSize = sizeMap.get(bHead);
|
||||
Node<V> big = aSetSize >= bSetSize ? aHead : bHead;
|
||||
Node<V> small = big == aHead ? bHead : aHead;
|
||||
parents.put(small, big);
|
||||
sizeMap.put(big, aSetSize + bSetSize);
|
||||
sizeMap.remove(small);
|
||||
}
|
||||
}
|
||||
|
||||
public int sets() {
|
||||
return sizeMap.size();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package class16;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Stack;
|
||||
|
||||
public class Code02_DFS {
|
||||
|
||||
public static void dfs(Node node) {
|
||||
if (node == null) {
|
||||
return;
|
||||
}
|
||||
Stack<Node> stack = new Stack<>();
|
||||
HashSet<Node> set = new HashSet<>();
|
||||
stack.add(node);
|
||||
set.add(node);
|
||||
System.out.println(node.value);
|
||||
while (!stack.isEmpty()) {
|
||||
Node cur = stack.pop();
|
||||
for (Node next : cur.nexts) {
|
||||
if (!set.contains(next)) {
|
||||
stack.push(cur);
|
||||
stack.push(next);
|
||||
set.add(next);
|
||||
System.out.println(next.value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,101 @@
|
||||
package class16;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
|
||||
//undirected graph only
|
||||
public class Code04_Kruskal {
|
||||
|
||||
// Union-Find Set
|
||||
public static class UnionFind {
|
||||
// key 某一个节点, value key节点往上的节点
|
||||
private HashMap<Node, Node> fatherMap;
|
||||
// key 某一个集合的代表节点, value key所在集合的节点个数
|
||||
private HashMap<Node, Integer> sizeMap;
|
||||
|
||||
public UnionFind() {
|
||||
fatherMap = new HashMap<Node, Node>();
|
||||
sizeMap = new HashMap<Node, Integer>();
|
||||
}
|
||||
|
||||
public void makeSets(Collection<Node> nodes) {
|
||||
fatherMap.clear();
|
||||
sizeMap.clear();
|
||||
for (Node node : nodes) {
|
||||
fatherMap.put(node, node);
|
||||
sizeMap.put(node, 1);
|
||||
}
|
||||
}
|
||||
|
||||
private Node findFather(Node n) {
|
||||
Stack<Node> path = new Stack<>();
|
||||
while(n != fatherMap.get(n)) {
|
||||
path.add(n);
|
||||
n = fatherMap.get(n);
|
||||
}
|
||||
while(!path.isEmpty()) {
|
||||
fatherMap.put(path.pop(), n);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
public boolean isSameSet(Node a, Node b) {
|
||||
return findFather(a) == findFather(b);
|
||||
}
|
||||
|
||||
public void union(Node a, Node b) {
|
||||
if (a == null || b == null) {
|
||||
return;
|
||||
}
|
||||
Node aDai = findFather(a);
|
||||
Node bDai = findFather(b);
|
||||
if (aDai != bDai) {
|
||||
int aSetSize = sizeMap.get(aDai);
|
||||
int bSetSize = sizeMap.get(bDai);
|
||||
if (aSetSize <= bSetSize) {
|
||||
fatherMap.put(aDai, bDai);
|
||||
sizeMap.put(bDai, aSetSize + bSetSize);
|
||||
sizeMap.remove(aDai);
|
||||
} else {
|
||||
fatherMap.put(bDai, aDai);
|
||||
sizeMap.put(aDai, aSetSize + bSetSize);
|
||||
sizeMap.remove(bDai);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class EdgeComparator implements Comparator<Edge> {
|
||||
|
||||
@Override
|
||||
public int compare(Edge o1, Edge o2) {
|
||||
return o1.weight - o2.weight;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static Set<Edge> kruskalMST(Graph graph) {
|
||||
UnionFind unionFind = new UnionFind();
|
||||
unionFind.makeSets(graph.nodes.values());
|
||||
// 从小的边到大的边,依次弹出,小根堆!
|
||||
PriorityQueue<Edge> priorityQueue = new PriorityQueue<>(new EdgeComparator());
|
||||
for (Edge edge : graph.edges) { // M 条边
|
||||
priorityQueue.add(edge); // O(logM)
|
||||
}
|
||||
Set<Edge> result = new HashSet<>();
|
||||
while (!priorityQueue.isEmpty()) { // M 条边
|
||||
Edge edge = priorityQueue.poll(); // O(logM)
|
||||
if (!unionFind.isSameSet(edge.from, edge.to)) { // O(1)
|
||||
result.add(edge);
|
||||
unionFind.union(edge.from, edge.to);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue