commit
5dce9076cd
@ -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,76 @@
|
||||
package class01;
|
||||
|
||||
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);
|
||||
int ans = getLessIndex(arr);
|
||||
if (!isRight(arr, ans)) {
|
||||
System.out.println("出错了!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
System.out.println("测试结束");
|
||||
}
|
||||
|
||||
}
|
@ -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,162 @@
|
||||
package class09;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Code01_LinkedListMid {
|
||||
|
||||
public static class Node {
|
||||
public int value;
|
||||
public Node next;
|
||||
|
||||
public Node(int v) {
|
||||
value = v;
|
||||
}
|
||||
}
|
||||
|
||||
// head 头
|
||||
public static Node midOrUpMidNode(Node head) {
|
||||
if (head == null || head.next == null || head.next.next == null) {
|
||||
return head;
|
||||
}
|
||||
// 链表有3个点或以上
|
||||
Node slow = head.next;
|
||||
Node fast = head.next.next;
|
||||
while (fast.next != null && fast.next.next != null) {
|
||||
slow = slow.next;
|
||||
fast = fast.next.next;
|
||||
}
|
||||
return slow;
|
||||
}
|
||||
|
||||
public static Node midOrDownMidNode(Node head) {
|
||||
if (head == null || head.next == null) {
|
||||
return head;
|
||||
}
|
||||
Node slow = head.next;
|
||||
Node fast = head.next;
|
||||
while (fast.next != null && fast.next.next != null) {
|
||||
slow = slow.next;
|
||||
fast = fast.next.next;
|
||||
}
|
||||
return slow;
|
||||
}
|
||||
|
||||
public static Node midOrUpMidPreNode(Node head) {
|
||||
if (head == null || head.next == null || head.next.next == null) {
|
||||
return null;
|
||||
}
|
||||
Node slow = head;
|
||||
Node fast = head.next.next;
|
||||
while (fast.next != null && fast.next.next != null) {
|
||||
slow = slow.next;
|
||||
fast = fast.next.next;
|
||||
}
|
||||
return slow;
|
||||
}
|
||||
|
||||
public static Node midOrDownMidPreNode(Node head) {
|
||||
if (head == null || head.next == null) {
|
||||
return null;
|
||||
}
|
||||
if (head.next.next == null) {
|
||||
return head;
|
||||
}
|
||||
Node slow = head;
|
||||
Node fast = head.next;
|
||||
while (fast.next != null && fast.next.next != null) {
|
||||
slow = slow.next;
|
||||
fast = fast.next.next;
|
||||
}
|
||||
return slow;
|
||||
}
|
||||
|
||||
public static Node right1(Node head) {
|
||||
if (head == null) {
|
||||
return null;
|
||||
}
|
||||
Node cur = head;
|
||||
ArrayList<Node> arr = new ArrayList<>();
|
||||
while (cur != null) {
|
||||
arr.add(cur);
|
||||
cur = cur.next;
|
||||
}
|
||||
return arr.get((arr.size() - 1) / 2);
|
||||
}
|
||||
|
||||
public static Node right2(Node head) {
|
||||
if (head == null) {
|
||||
return null;
|
||||
}
|
||||
Node cur = head;
|
||||
ArrayList<Node> arr = new ArrayList<>();
|
||||
while (cur != null) {
|
||||
arr.add(cur);
|
||||
cur = cur.next;
|
||||
}
|
||||
return arr.get(arr.size() / 2);
|
||||
}
|
||||
|
||||
public static Node right3(Node head) {
|
||||
if (head == null || head.next == null || head.next.next == null) {
|
||||
return null;
|
||||
}
|
||||
Node cur = head;
|
||||
ArrayList<Node> arr = new ArrayList<>();
|
||||
while (cur != null) {
|
||||
arr.add(cur);
|
||||
cur = cur.next;
|
||||
}
|
||||
return arr.get((arr.size() - 3) / 2);
|
||||
}
|
||||
|
||||
public static Node right4(Node head) {
|
||||
if (head == null || head.next == null) {
|
||||
return null;
|
||||
}
|
||||
Node cur = head;
|
||||
ArrayList<Node> arr = new ArrayList<>();
|
||||
while (cur != null) {
|
||||
arr.add(cur);
|
||||
cur = cur.next;
|
||||
}
|
||||
return arr.get((arr.size() - 2) / 2);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Node test = null;
|
||||
test = new Node(0);
|
||||
test.next = new Node(1);
|
||||
test.next.next = new Node(2);
|
||||
test.next.next.next = new Node(3);
|
||||
test.next.next.next.next = new Node(4);
|
||||
test.next.next.next.next.next = new Node(5);
|
||||
test.next.next.next.next.next.next = new Node(6);
|
||||
test.next.next.next.next.next.next.next = new Node(7);
|
||||
test.next.next.next.next.next.next.next.next = new Node(8);
|
||||
|
||||
Node ans1 = null;
|
||||
Node ans2 = null;
|
||||
|
||||
ans1 = midOrUpMidNode(test);
|
||||
ans2 = right1(test);
|
||||
System.out.println(ans1 != null ? ans1.value : "无");
|
||||
System.out.println(ans2 != null ? ans2.value : "无");
|
||||
|
||||
ans1 = midOrDownMidNode(test);
|
||||
ans2 = right2(test);
|
||||
System.out.println(ans1 != null ? ans1.value : "无");
|
||||
System.out.println(ans2 != null ? ans2.value : "无");
|
||||
|
||||
ans1 = midOrUpMidPreNode(test);
|
||||
ans2 = right3(test);
|
||||
System.out.println(ans1 != null ? ans1.value : "无");
|
||||
System.out.println(ans2 != null ? ans2.value : "无");
|
||||
|
||||
ans1 = midOrDownMidPreNode(test);
|
||||
ans2 = right4(test);
|
||||
System.out.println(ans1 != null ? ans1.value : "无");
|
||||
System.out.println(ans2 != null ? ans2.value : "无");
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -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 = 1000000;
|
||||
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,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,120 @@
|
||||
package class13;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
// 测试链接 : https://leetcode.com/problems/check-completeness-of-a-binary-tree/
|
||||
|
||||
public class Code01_IsCBT {
|
||||
|
||||
// 不要提交这个类
|
||||
public static class TreeNode {
|
||||
public int val;
|
||||
public TreeNode left;
|
||||
public TreeNode right;
|
||||
|
||||
public TreeNode(int v) {
|
||||
val = v;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isCompleteTree1(TreeNode head) {
|
||||
if (head == null) {
|
||||
return true;
|
||||
}
|
||||
LinkedList<TreeNode> queue = new LinkedList<>();
|
||||
// 是否遇到过左右两个孩子不双全的节点
|
||||
boolean leaf = false;
|
||||
TreeNode l = null;
|
||||
TreeNode 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 isCompleteTree2(TreeNode 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(TreeNode 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 TreeNode generateRandomBST(int maxLevel, int maxValue) {
|
||||
return generate(1, maxLevel, maxValue);
|
||||
}
|
||||
|
||||
// for test
|
||||
public static TreeNode generate(int level, int maxLevel, int maxValue) {
|
||||
if (level > maxLevel || Math.random() < 0.5) {
|
||||
return null;
|
||||
}
|
||||
TreeNode head = new TreeNode((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++) {
|
||||
TreeNode head = generateRandomBST(maxLevel, maxValue);
|
||||
if (isCompleteTree1(head) != isCompleteTree2(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,58 @@
|
||||
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,70 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package class16;
|
||||
|
||||
public class Edge {
|
||||
public int weight;
|
||||
public Node from;
|
||||
public Node to;
|
||||
|
||||
public Edge(int weight, Node from, Node to) {
|
||||
this.weight = weight;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package class16;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class Graph {
|
||||
public HashMap<Integer, Node> nodes;
|
||||
public HashSet<Edge> edges;
|
||||
|
||||
public Graph() {
|
||||
nodes = new HashMap<>();
|
||||
edges = new HashSet<>();
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package class16;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
// 点结构的描述
|
||||
public class Node {
|
||||
public int value;
|
||||
public int in;
|
||||
public int out;
|
||||
public ArrayList<Node> nexts;
|
||||
public ArrayList<Edge> edges;
|
||||
|
||||
public Node(int value) {
|
||||
this.value = value;
|
||||
in = 0;
|
||||
out = 0;
|
||||
nexts = new ArrayList<>();
|
||||
edges = new ArrayList<>();
|
||||
}
|
||||
}
|
@ -0,0 +1,139 @@
|
||||
package class17;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
public class Code02_Hanoi {
|
||||
|
||||
public static void hanoi1(int n) {
|
||||
leftToRight(n);
|
||||
}
|
||||
|
||||
// 请把1~N层圆盘 从左 -> 右
|
||||
public static void leftToRight(int n) {
|
||||
if (n == 1) { // base case
|
||||
System.out.println("Move 1 from left to right");
|
||||
return;
|
||||
}
|
||||
leftToMid(n - 1);
|
||||
System.out.println("Move " + n + " from left to right");
|
||||
midToRight(n - 1);
|
||||
}
|
||||
|
||||
// 请把1~N层圆盘 从左 -> 中
|
||||
public static void leftToMid(int n) {
|
||||
if (n == 1) {
|
||||
System.out.println("Move 1 from left to mid");
|
||||
return;
|
||||
}
|
||||
leftToRight(n - 1);
|
||||
System.out.println("Move " + n + " from left to mid");
|
||||
rightToMid(n - 1);
|
||||
}
|
||||
|
||||
public static void rightToMid(int n) {
|
||||
if (n == 1) {
|
||||
System.out.println("Move 1 from right to mid");
|
||||
return;
|
||||
}
|
||||
rightToLeft(n - 1);
|
||||
System.out.println("Move " + n + " from right to mid");
|
||||
leftToMid(n - 1);
|
||||
}
|
||||
|
||||
public static void midToRight(int n) {
|
||||
if (n == 1) {
|
||||
System.out.println("Move 1 from mid to right");
|
||||
return;
|
||||
}
|
||||
midToLeft(n - 1);
|
||||
System.out.println("Move " + n + " from mid to right");
|
||||
leftToRight(n - 1);
|
||||
}
|
||||
|
||||
public static void midToLeft(int n) {
|
||||
if (n == 1) {
|
||||
System.out.println("Move 1 from mid to left");
|
||||
return;
|
||||
}
|
||||
midToRight(n - 1);
|
||||
System.out.println("Move " + n + " from mid to left");
|
||||
rightToLeft(n - 1);
|
||||
}
|
||||
|
||||
public static void rightToLeft(int n) {
|
||||
if (n == 1) {
|
||||
System.out.println("Move 1 from right to left");
|
||||
return;
|
||||
}
|
||||
rightToMid(n - 1);
|
||||
System.out.println("Move " + n + " from right to left");
|
||||
midToLeft(n - 1);
|
||||
}
|
||||
|
||||
public static void hanoi2(int n) {
|
||||
if (n > 0) {
|
||||
func(n, "left", "right", "mid");
|
||||
}
|
||||
}
|
||||
|
||||
public static void func(int N, String from, String to, String other) {
|
||||
if (N == 1) { // base
|
||||
System.out.println("Move 1 from " + from + " to " + to);
|
||||
} else {
|
||||
func(N - 1, from, other, to);
|
||||
System.out.println("Move " + N + " from " + from + " to " + to);
|
||||
func(N - 1, other, to, from);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Record {
|
||||
public boolean finish1;
|
||||
public int base;
|
||||
public String from;
|
||||
public String to;
|
||||
public String other;
|
||||
|
||||
public Record(boolean f1, int b, String f, String t, String o) {
|
||||
finish1 = false;
|
||||
base = b;
|
||||
from = f;
|
||||
to = t;
|
||||
other = o;
|
||||
}
|
||||
}
|
||||
|
||||
public static void hanoi3(int N) {
|
||||
if (N < 1) {
|
||||
return;
|
||||
}
|
||||
Stack<Record> stack = new Stack<>();
|
||||
stack.add(new Record(false, N, "left", "right", "mid"));
|
||||
while (!stack.isEmpty()) {
|
||||
Record cur = stack.pop();
|
||||
if (cur.base == 1) {
|
||||
System.out.println("Move 1 from " + cur.from + " to " + cur.to);
|
||||
if (!stack.isEmpty()) {
|
||||
stack.peek().finish1 = true;
|
||||
}
|
||||
} else {
|
||||
if (!cur.finish1) {
|
||||
stack.push(cur);
|
||||
stack.push(new Record(false, cur.base - 1, cur.from, cur.other, cur.to));
|
||||
} else {
|
||||
System.out.println("Move " + cur.base + " from " + cur.from + " to " + cur.to);
|
||||
stack.push(new Record(false, cur.base - 1, cur.other, cur.to, cur.from));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int n = 3;
|
||||
hanoi1(n);
|
||||
System.out.println("============");
|
||||
hanoi2(n);
|
||||
// System.out.println("============");
|
||||
// hanoi3(n);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
package class17;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Code04_PrintAllPermutations {
|
||||
|
||||
public static List<String> permutation1(String s) {
|
||||
List<String> ans = new ArrayList<>();
|
||||
if (s == null || s.length() == 0) {
|
||||
return ans;
|
||||
}
|
||||
char[] str = s.toCharArray();
|
||||
ArrayList<Character> rest = new ArrayList<Character>();
|
||||
for (char cha : str) {
|
||||
rest.add(cha);
|
||||
}
|
||||
String path = "";
|
||||
f(rest, path, ans);
|
||||
return ans;
|
||||
}
|
||||
|
||||
public static void f(ArrayList<Character> rest, String path, List<String> ans) {
|
||||
if (rest.isEmpty()) {
|
||||
ans.add(path);
|
||||
} else {
|
||||
int N = rest.size();
|
||||
for (int i = 0; i < N; i++) {
|
||||
char cur = rest.get(i);
|
||||
rest.remove(i);
|
||||
f(rest, path + cur, ans);
|
||||
rest.add(i, cur);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static List<String> permutation2(String s) {
|
||||
List<String> ans = new ArrayList<>();
|
||||
if (s == null || s.length() == 0) {
|
||||
return ans;
|
||||
}
|
||||
char[] str = s.toCharArray();
|
||||
g1(str, 0, ans);
|
||||
return ans;
|
||||
}
|
||||
|
||||
public static void g1(char[] str, int index, List<String> ans) {
|
||||
if (index == str.length) {
|
||||
ans.add(String.valueOf(str));
|
||||
} else {
|
||||
for (int i = index; i < str.length; i++) {
|
||||
swap(str, index, i);
|
||||
g1(str, index + 1, ans);
|
||||
swap(str, index, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static List<String> permutation3(String s) {
|
||||
List<String> ans = new ArrayList<>();
|
||||
if (s == null || s.length() == 0) {
|
||||
return ans;
|
||||
}
|
||||
char[] str = s.toCharArray();
|
||||
g2(str, 0, ans);
|
||||
return ans;
|
||||
}
|
||||
|
||||
public static void g2(char[] str, int index, List<String> ans) {
|
||||
if (index == str.length) {
|
||||
ans.add(String.valueOf(str));
|
||||
} else {
|
||||
boolean[] visited = new boolean[256];
|
||||
for (int i = index; i < str.length; i++) {
|
||||
if (!visited[str[i]]) {
|
||||
visited[str[i]] = true;
|
||||
swap(str, index, i);
|
||||
g2(str, index + 1, ans);
|
||||
swap(str, index, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void swap(char[] chs, int i, int j) {
|
||||
char tmp = chs[i];
|
||||
chs[i] = chs[j];
|
||||
chs[j] = tmp;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
String s = "acc";
|
||||
List<String> ans1 = permutation1(s);
|
||||
for (String str : ans1) {
|
||||
System.out.println(str);
|
||||
}
|
||||
System.out.println("=======");
|
||||
List<String> ans2 = permutation2(s);
|
||||
for (String str : ans2) {
|
||||
System.out.println(str);
|
||||
}
|
||||
System.out.println("=======");
|
||||
List<String> ans3 = permutation3(s);
|
||||
for (String str : ans3) {
|
||||
System.out.println(str);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package class17;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
public class Code05_ReverseStackUsingRecursive {
|
||||
|
||||
public static void reverse(Stack<Integer> stack) {
|
||||
if (stack.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
int i = f(stack);
|
||||
reverse(stack);
|
||||
stack.push(i);
|
||||
}
|
||||
|
||||
// 栈底元素移除掉
|
||||
// 上面的元素盖下来
|
||||
// 返回移除掉的栈底元素
|
||||
public static int f(Stack<Integer> stack) {
|
||||
int result = stack.pop();
|
||||
if (stack.isEmpty()) {
|
||||
return result;
|
||||
} else {
|
||||
int last = f(stack);
|
||||
stack.push(result);
|
||||
return last;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Stack<Integer> test = new Stack<Integer>();
|
||||
test.push(1);
|
||||
test.push(2);
|
||||
test.push(3);
|
||||
test.push(4);
|
||||
test.push(5);
|
||||
reverse(test);
|
||||
while (!test.isEmpty()) {
|
||||
System.out.println(test.pop());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package class17;
|
||||
|
||||
public class Edge {
|
||||
public int weight;
|
||||
public Node from;
|
||||
public Node to;
|
||||
|
||||
public Edge(int weight, Node from, Node to) {
|
||||
this.weight = weight;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package class17;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class Graph {
|
||||
public HashMap<Integer, Node> nodes;
|
||||
public HashSet<Edge> edges;
|
||||
|
||||
public Graph() {
|
||||
nodes = new HashMap<>();
|
||||
edges = new HashSet<>();
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package class17;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
// 点结构的描述
|
||||
public class Node {
|
||||
public int value;
|
||||
public int in;
|
||||
public int out;
|
||||
public ArrayList<Node> nexts;
|
||||
public ArrayList<Edge> edges;
|
||||
|
||||
public Node(int value) {
|
||||
this.value = value;
|
||||
in = 0;
|
||||
out = 0;
|
||||
nexts = new ArrayList<>();
|
||||
edges = new ArrayList<>();
|
||||
}
|
||||
}
|
@ -0,0 +1,116 @@
|
||||
package class18;
|
||||
|
||||
public class Code02_CardsInLine {
|
||||
|
||||
// 根据规则,返回获胜者的分数
|
||||
public static int win1(int[] arr) {
|
||||
if (arr == null || arr.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
int first = f1(arr, 0, arr.length - 1);
|
||||
int second = g1(arr, 0, arr.length - 1);
|
||||
return Math.max(first, second);
|
||||
}
|
||||
|
||||
// arr[L..R],先手获得的最好分数返回
|
||||
public static int f1(int[] arr, int L, int R) {
|
||||
if (L == R) {
|
||||
return arr[L];
|
||||
}
|
||||
int p1 = arr[L] + g1(arr, L + 1, R);
|
||||
int p2 = arr[R] + g1(arr, L, R - 1);
|
||||
return Math.max(p1, p2);
|
||||
}
|
||||
|
||||
// // arr[L..R],后手获得的最好分数返回
|
||||
public static int g1(int[] arr, int L, int R) {
|
||||
if (L == R) {
|
||||
return 0;
|
||||
}
|
||||
int p1 = f1(arr, L + 1, R); // 对手拿走了L位置的数
|
||||
int p2 = f1(arr, L, R - 1); // 对手拿走了R位置的数
|
||||
return Math.min(p1, p2);
|
||||
}
|
||||
|
||||
public static int win2(int[] arr) {
|
||||
if (arr == null || arr.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
int N = arr.length;
|
||||
int[][] fmap = new int[N][N];
|
||||
int[][] gmap = new int[N][N];
|
||||
for (int i = 0; i < N; i++) {
|
||||
for (int j = 0; j < N; j++) {
|
||||
fmap[i][j] = -1;
|
||||
gmap[i][j] = -1;
|
||||
}
|
||||
}
|
||||
int first = f2(arr, 0, arr.length - 1, fmap, gmap);
|
||||
int second = g2(arr, 0, arr.length - 1, fmap, gmap);
|
||||
return Math.max(first, second);
|
||||
}
|
||||
|
||||
// arr[L..R],先手获得的最好分数返回
|
||||
public static int f2(int[] arr, int L, int R, int[][] fmap, int[][] gmap) {
|
||||
if (fmap[L][R] != -1) {
|
||||
return fmap[L][R];
|
||||
}
|
||||
int ans = 0;
|
||||
if (L == R) {
|
||||
ans = arr[L];
|
||||
} else {
|
||||
int p1 = arr[L] + g2(arr, L + 1, R, fmap, gmap);
|
||||
int p2 = arr[R] + g2(arr, L, R - 1, fmap, gmap);
|
||||
ans = Math.max(p1, p2);
|
||||
}
|
||||
fmap[L][R] = ans;
|
||||
return ans;
|
||||
}
|
||||
|
||||
// // arr[L..R],后手获得的最好分数返回
|
||||
public static int g2(int[] arr, int L, int R, int[][] fmap, int[][] gmap) {
|
||||
if (gmap[L][R] != -1) {
|
||||
return gmap[L][R];
|
||||
}
|
||||
int ans = 0;
|
||||
if (L != R) {
|
||||
int p1 = f2(arr, L + 1, R, fmap, gmap); // 对手拿走了L位置的数
|
||||
int p2 = f2(arr, L, R - 1, fmap, gmap); // 对手拿走了R位置的数
|
||||
ans = Math.min(p1, p2);
|
||||
}
|
||||
gmap[L][R] = ans;
|
||||
return ans;
|
||||
}
|
||||
|
||||
public static int win3(int[] arr) {
|
||||
if (arr == null || arr.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
int N = arr.length;
|
||||
int[][] fmap = new int[N][N];
|
||||
int[][] gmap = new int[N][N];
|
||||
for (int i = 0; i < N; i++) {
|
||||
fmap[i][i] = arr[i];
|
||||
}
|
||||
for (int startCol = 1; startCol < N; startCol++) {
|
||||
int L = 0;
|
||||
int R = startCol;
|
||||
while (R < N) {
|
||||
fmap[L][R] = Math.max(arr[L] + gmap[L + 1][R], arr[R] + gmap[L][R - 1]);
|
||||
gmap[L][R] = Math.min(fmap[L + 1][R], fmap[L][R - 1]);
|
||||
L++;
|
||||
R++;
|
||||
}
|
||||
}
|
||||
return Math.max(fmap[0][N - 1], gmap[0][N - 1]);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int[] arr = { 5, 7, 4, 5, 8, 1, 6, 0, 3, 4, 6, 1, 7 };
|
||||
System.out.println(win1(arr));
|
||||
System.out.println(win2(arr));
|
||||
System.out.println(win3(arr));
|
||||
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue