commit
173a95b19f
@ -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,30 @@
|
||||
package class01;
|
||||
|
||||
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) {
|
||||
// mid = (L+R) / 2;
|
||||
// L 10亿 R 18亿
|
||||
// mid = L + (R - L) / 2
|
||||
// N / 2 N >> 1
|
||||
mid = L + ((R - L) >> 1); // mid = (L + R) / 2
|
||||
if (sortedArr[mid] == num) {
|
||||
return true;
|
||||
} else if (sortedArr[mid] > num) {
|
||||
R = mid - 1;
|
||||
} else {
|
||||
L = mid + 1;
|
||||
}
|
||||
}
|
||||
return sortedArr[L] == num;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
package class01;
|
||||
|
||||
public class Code06_BSAwesome {
|
||||
|
||||
public static int getLessIndex(int[] arr) {
|
||||
if (arr == null || arr.length == 0) {
|
||||
return -1; // no exist
|
||||
}
|
||||
if (arr.length == 1 || arr[0] < arr[1]) {
|
||||
return 0;
|
||||
}
|
||||
if (arr[arr.length - 1] < arr[arr.length - 2]) {
|
||||
return arr.length - 1;
|
||||
}
|
||||
int left = 1;
|
||||
int right = arr.length - 2;
|
||||
int mid = 0;
|
||||
while (left < right) {
|
||||
mid = (left + right) / 2;
|
||||
if (arr[mid] > arr[mid - 1]) {
|
||||
right = mid - 1;
|
||||
} else if (arr[mid] > arr[mid + 1]) {
|
||||
left = mid + 1;
|
||||
} else {
|
||||
return mid;
|
||||
}
|
||||
}
|
||||
return left;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
package class01;
|
||||
|
||||
public class Test {
|
||||
|
||||
public static void main(String[] args) {
|
||||
int a = 6;
|
||||
int b = 6;
|
||||
|
||||
|
||||
a = a ^ b;
|
||||
b = a ^ b;
|
||||
a = a ^ b;
|
||||
|
||||
|
||||
System.out.println(a);
|
||||
System.out.println(b);
|
||||
|
||||
|
||||
|
||||
|
||||
int[] arr = {3,1,100};
|
||||
|
||||
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,198 @@
|
||||
package class02;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// 要求无环,有环别用这个函数
|
||||
public static boolean checkLinkedListEqual(Node head1, Node head2) {
|
||||
while (head1 != null && head2 != null) {
|
||||
if (head1.value != head2.value) {
|
||||
return false;
|
||||
}
|
||||
head1 = head1.next;
|
||||
head2 = head2.next;
|
||||
}
|
||||
return head1 == null && head2 == null;
|
||||
}
|
||||
|
||||
// 要求无环,有环别用这个函数
|
||||
public static boolean checkDoubleListEqual(DoubleNode head1, DoubleNode head2) {
|
||||
boolean null1 = head1 == null;
|
||||
boolean null2 = head2 == null;
|
||||
if (null1 && null2) {
|
||||
return true;
|
||||
}
|
||||
if (null1 ^ null2) {
|
||||
return false;
|
||||
}
|
||||
if (head1.last != null || head2.last != null) {
|
||||
return false;
|
||||
}
|
||||
DoubleNode end1 = null;
|
||||
DoubleNode end2 = null;
|
||||
while (head1 != null && head2 != null) {
|
||||
if (head1.value != head2.value) {
|
||||
return false;
|
||||
}
|
||||
end1 = head1;
|
||||
end2 = head2;
|
||||
head1 = head1.next;
|
||||
head2 = head2.next;
|
||||
}
|
||||
if (head1 != null || head2 != null) {
|
||||
return false;
|
||||
}
|
||||
while (end1 != null && end2 != null) {
|
||||
if (end1.value != end2.value) {
|
||||
return false;
|
||||
}
|
||||
end1 = end1.last;
|
||||
end2 = end2.last;
|
||||
}
|
||||
return end1 == null && end2 == null;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int len = 50;
|
||||
int value = 100;
|
||||
int testTime = 100000;
|
||||
for (int i = 0; i < testTime; i++) {
|
||||
Node node1 = generateRandomLinkedList(len, value);
|
||||
Node reverse1 = reverseLinkedList(node1);
|
||||
Node back1 = testReverseLinkedList(reverse1);
|
||||
if (!checkLinkedListEqual(node1, back1)) {
|
||||
System.out.println("oops!");
|
||||
break;
|
||||
}
|
||||
DoubleNode node2 = generateRandomDoubleList(len, value);
|
||||
DoubleNode reverse2 = reverseDoubleList(node2);
|
||||
DoubleNode back2 = testReverseDoubleList(reverse2);
|
||||
if (!checkDoubleListEqual(node2, back2)) {
|
||||
System.out.println("oops!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
System.out.println("finish!");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
package class02;
|
||||
|
||||
public class Code02_DeleteGivenValue {
|
||||
|
||||
public static class Node {
|
||||
public int value;
|
||||
public Node next;
|
||||
|
||||
public Node(int data) {
|
||||
this.value = data;
|
||||
}
|
||||
}
|
||||
|
||||
public static Node removeValue(Node head, int num) {
|
||||
while (head != null) {
|
||||
if (head.value != num) {
|
||||
break;
|
||||
}
|
||||
head = head.next;
|
||||
}
|
||||
// head来到 第一个不需要删的位置
|
||||
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 class02;
|
||||
|
||||
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 (stack.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 class02;
|
||||
|
||||
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 class02;
|
||||
|
||||
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 class02;
|
||||
|
||||
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,256 @@
|
||||
package class04;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.PriorityQueue;
|
||||
|
||||
public class Code03_Heap02 {
|
||||
|
||||
// 堆
|
||||
public static class MyHeap<T> {
|
||||
private ArrayList<T> heap;
|
||||
private HashMap<T, Integer> indexMap;
|
||||
private int heapSize;
|
||||
private Comparator<? super T> comparator;
|
||||
|
||||
public MyHeap(Comparator<? super T> com) {
|
||||
heap = new ArrayList<>();
|
||||
indexMap = new HashMap<>();
|
||||
heapSize = 0;
|
||||
comparator = com;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return heapSize == 0;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return heapSize;
|
||||
}
|
||||
|
||||
public boolean contains(T key) {
|
||||
return indexMap.containsKey(key);
|
||||
}
|
||||
|
||||
public void push(T value) {
|
||||
heap.add(value);
|
||||
indexMap.put(value, heapSize);
|
||||
heapInsert(heapSize++);
|
||||
}
|
||||
|
||||
public T pop() {
|
||||
T ans = heap.get(0);
|
||||
int end = heapSize - 1;
|
||||
swap(0, end);
|
||||
heap.remove(end);
|
||||
indexMap.remove(ans);
|
||||
heapify(0, --heapSize);
|
||||
return ans;
|
||||
}
|
||||
|
||||
public void resign(T value) {
|
||||
int valueIndex = indexMap.get(value);
|
||||
heapInsert(valueIndex);
|
||||
heapify(valueIndex, heapSize);
|
||||
}
|
||||
|
||||
private void heapInsert(int index) {
|
||||
while (comparator.compare(heap.get(index), heap.get((index - 1) / 2)) < 0) {
|
||||
swap(index, (index - 1) / 2);
|
||||
index = (index - 1) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
private void heapify(int index, int heapSize) {
|
||||
int left = index * 2 + 1;
|
||||
while (left < heapSize) {
|
||||
int largest = left + 1 < heapSize && (comparator.compare(heap.get(left + 1), heap.get(left)) < 0)
|
||||
? left + 1
|
||||
: left;
|
||||
largest = comparator.compare(heap.get(largest), heap.get(index)) < 0 ? largest : index;
|
||||
if (largest == index) {
|
||||
break;
|
||||
}
|
||||
swap(largest, index);
|
||||
index = largest;
|
||||
left = index * 2 + 1;
|
||||
}
|
||||
}
|
||||
|
||||
private void swap(int i, int j) {
|
||||
T o1 = heap.get(i);
|
||||
T o2 = heap.get(j);
|
||||
heap.set(i, o2);
|
||||
heap.set(j, o1);
|
||||
indexMap.put(o1, j);
|
||||
indexMap.put(o2, i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Student {
|
||||
public int classNo;
|
||||
public int age;
|
||||
public int id;
|
||||
|
||||
public Student(int c, int a, int i) {
|
||||
classNo = c;
|
||||
age = a;
|
||||
id = i;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class StudentComparator implements Comparator<Student> {
|
||||
|
||||
@Override
|
||||
public int compare(Student o1, Student o2) {
|
||||
return o1.age - o2.age;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Student s1 = null;
|
||||
Student s2 = null;
|
||||
Student s3 = null;
|
||||
Student s4 = null;
|
||||
Student s5 = null;
|
||||
Student s6 = null;
|
||||
|
||||
s1 = new Student(2, 50, 11111);
|
||||
s2 = new Student(1, 60, 22222);
|
||||
s3 = new Student(6, 10, 33333);
|
||||
s4 = new Student(3, 20, 44444);
|
||||
s5 = new Student(7, 72, 55555);
|
||||
s6 = new Student(1, 14, 66666);
|
||||
|
||||
PriorityQueue<Student> heap = new PriorityQueue<>(new StudentComparator());
|
||||
heap.add(s1);
|
||||
heap.add(s2);
|
||||
heap.add(s3);
|
||||
heap.add(s4);
|
||||
heap.add(s5);
|
||||
heap.add(s6);
|
||||
while (!heap.isEmpty()) {
|
||||
Student cur = heap.poll();
|
||||
System.out.println(cur.classNo + "," + cur.age + "," + cur.id);
|
||||
}
|
||||
|
||||
System.out.println("===============");
|
||||
|
||||
MyHeap<Student> myHeap = new MyHeap<>(new StudentComparator());
|
||||
myHeap.push(s1);
|
||||
myHeap.push(s2);
|
||||
myHeap.push(s3);
|
||||
myHeap.push(s4);
|
||||
myHeap.push(s5);
|
||||
myHeap.push(s6);
|
||||
while (!myHeap.isEmpty()) {
|
||||
Student cur = myHeap.pop();
|
||||
System.out.println(cur.classNo + "," + cur.age + "," + cur.id);
|
||||
}
|
||||
|
||||
System.out.println("===============");
|
||||
|
||||
s1 = new Student(2, 50, 11111);
|
||||
s2 = new Student(1, 60, 22222);
|
||||
s3 = new Student(6, 10, 33333);
|
||||
s4 = new Student(3, 20, 44444);
|
||||
s5 = new Student(7, 72, 55555);
|
||||
s6 = new Student(1, 14, 66666);
|
||||
|
||||
heap = new PriorityQueue<>(new StudentComparator());
|
||||
|
||||
heap.add(s1);
|
||||
heap.add(s2);
|
||||
heap.add(s3);
|
||||
heap.add(s4);
|
||||
heap.add(s5);
|
||||
heap.add(s6);
|
||||
|
||||
s2.age = 6;
|
||||
s4.age = 12;
|
||||
s5.age = 10;
|
||||
s6.age = 84;
|
||||
|
||||
while (!heap.isEmpty()) {
|
||||
Student cur = heap.poll();
|
||||
System.out.println(cur.classNo + "," + cur.age + "," + cur.id);
|
||||
}
|
||||
|
||||
System.out.println("===============");
|
||||
|
||||
s1 = new Student(2, 50, 11111);
|
||||
s2 = new Student(1, 60, 22222);
|
||||
s3 = new Student(6, 10, 33333);
|
||||
s4 = new Student(3, 20, 44444);
|
||||
s5 = new Student(7, 72, 55555);
|
||||
s6 = new Student(1, 14, 66666);
|
||||
|
||||
myHeap = new MyHeap<>(new StudentComparator());
|
||||
|
||||
myHeap.push(s1);
|
||||
myHeap.push(s2);
|
||||
myHeap.push(s3);
|
||||
myHeap.push(s4);
|
||||
myHeap.push(s5);
|
||||
myHeap.push(s6);
|
||||
|
||||
s2.age = 6;
|
||||
myHeap.resign(s2);
|
||||
s4.age = 12;
|
||||
myHeap.resign(s4);
|
||||
s5.age = 10;
|
||||
myHeap.resign(s5);
|
||||
s6.age = 84;
|
||||
myHeap.resign(s6);
|
||||
|
||||
while (!myHeap.isEmpty()) {
|
||||
Student cur = myHeap.pop();
|
||||
System.out.println(cur.classNo + "," + cur.age + "," + cur.id);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 对数器
|
||||
System.out.println("test begin");
|
||||
int maxValue = 100000;
|
||||
int pushTime = 1000000;
|
||||
int resignTime = 100;
|
||||
MyHeap<Student> test = new MyHeap<>(new StudentComparator());
|
||||
ArrayList<Student> list = new ArrayList<>();
|
||||
for(int i = 0 ; i < pushTime; i++) {
|
||||
Student cur = new Student(1,(int) (Math.random() * maxValue), 1000);
|
||||
list.add(cur);
|
||||
test.push(cur);
|
||||
}
|
||||
for(int i = 0 ; i < resignTime; i++) {
|
||||
int index = (int)(Math.random() * pushTime);
|
||||
list.get(index).age = (int) (Math.random() * maxValue);
|
||||
test.resign(list.get(index));
|
||||
}
|
||||
int preAge = Integer.MIN_VALUE;
|
||||
while(test.isEmpty()) {
|
||||
Student cur = test.pop();
|
||||
if(cur.age < preAge) {
|
||||
System.out.println("Oops!");
|
||||
}
|
||||
preAge = cur.age;
|
||||
}
|
||||
System.out.println("test finish");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,111 @@
|
||||
package class05;
|
||||
|
||||
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,153 @@
|
||||
package class05;
|
||||
|
||||
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
|
||||
// l..r 3 56 17 100 3
|
||||
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 class06;
|
||||
|
||||
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 class06;
|
||||
|
||||
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,130 @@
|
||||
package class06;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class Code04_CopyListWithRandom {
|
||||
|
||||
public static class Node {
|
||||
public int value;
|
||||
public Node next;
|
||||
public Node rand;
|
||||
|
||||
public Node(int data) {
|
||||
this.value = data;
|
||||
}
|
||||
}
|
||||
|
||||
public static Node copyListWithRand1(Node head) {
|
||||
HashMap<Node, Node> map = new HashMap<Node, Node>();
|
||||
Node cur = head;
|
||||
while (cur != null) {
|
||||
map.put(cur, new Node(cur.value));
|
||||
cur = cur.next;
|
||||
}
|
||||
cur = head;
|
||||
while (cur != null) {
|
||||
// cur 老
|
||||
// map.get(cur) 新
|
||||
map.get(cur).next = map.get(cur.next);
|
||||
map.get(cur).rand = map.get(cur.rand);
|
||||
cur = cur.next;
|
||||
}
|
||||
return map.get(head);
|
||||
}
|
||||
|
||||
public static Node copyListWithRand2(Node head) {
|
||||
if (head == null) {
|
||||
return null;
|
||||
}
|
||||
Node cur = head;
|
||||
Node next = null;
|
||||
// copy node and link to every node
|
||||
// 1 -> 2
|
||||
// 1 -> 1' -> 2
|
||||
while (cur != null) {
|
||||
// cur 老 next 老的下一个
|
||||
next = cur.next;
|
||||
cur.next = new Node(cur.value);
|
||||
cur.next.next = next;
|
||||
cur = next;
|
||||
}
|
||||
cur = head;
|
||||
Node curCopy = null;
|
||||
// set copy node rand
|
||||
// 1 -> 1' -> 2 -> 2'
|
||||
while (cur != null) {
|
||||
// cur 老
|
||||
// cur.next 新 copy
|
||||
next = cur.next.next;
|
||||
curCopy = cur.next;
|
||||
curCopy.rand = cur.rand != null ? cur.rand.next : null;
|
||||
cur = next;
|
||||
}
|
||||
// head head.next
|
||||
Node res = head.next;
|
||||
cur = head;
|
||||
// split
|
||||
while (cur != null) {
|
||||
next = cur.next.next;
|
||||
curCopy = cur.next;
|
||||
cur.next = next;
|
||||
curCopy.next = next != null ? next.next : null;
|
||||
cur = next;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public static void printRandLinkedList(Node head) {
|
||||
Node cur = head;
|
||||
System.out.print("order: ");
|
||||
while (cur != null) {
|
||||
System.out.print(cur.value + " ");
|
||||
cur = cur.next;
|
||||
}
|
||||
System.out.println();
|
||||
cur = head;
|
||||
System.out.print("rand: ");
|
||||
while (cur != null) {
|
||||
System.out.print(cur.rand == null ? "- " : cur.rand.value + " ");
|
||||
cur = cur.next;
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Node head = null;
|
||||
Node res1 = null;
|
||||
Node res2 = null;
|
||||
printRandLinkedList(head);
|
||||
res1 = copyListWithRand1(head);
|
||||
printRandLinkedList(res1);
|
||||
res2 = copyListWithRand2(head);
|
||||
printRandLinkedList(res2);
|
||||
printRandLinkedList(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(4);
|
||||
head.next.next.next.next = new Node(5);
|
||||
head.next.next.next.next.next = new Node(6);
|
||||
|
||||
head.rand = head.next.next.next.next.next; // 1 -> 6
|
||||
head.next.rand = head.next.next.next.next.next; // 2 -> 6
|
||||
head.next.next.rand = head.next.next.next.next; // 3 -> 5
|
||||
head.next.next.next.rand = head.next.next; // 4 -> 3
|
||||
head.next.next.next.next.rand = null; // 5 -> null
|
||||
head.next.next.next.next.next.rand = head.next.next.next; // 6 -> 4
|
||||
|
||||
printRandLinkedList(head);
|
||||
res1 = copyListWithRand1(head);
|
||||
printRandLinkedList(res1);
|
||||
res2 = copyListWithRand2(head);
|
||||
printRandLinkedList(res2);
|
||||
printRandLinkedList(head);
|
||||
System.out.println("=========================");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
package class06;
|
||||
|
||||
public class Test {
|
||||
|
||||
public static class Node{
|
||||
public int value;
|
||||
public Node next;
|
||||
public Node(int v) {
|
||||
value = v;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Node a = new Node(1);
|
||||
Node b = new Node(2);
|
||||
Node c = new Node(3);
|
||||
|
||||
a.next = b;
|
||||
b.next = c;
|
||||
|
||||
c = null;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,72 @@
|
||||
package class07;
|
||||
|
||||
public class Code01_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,117 @@
|
||||
package class07;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
public class Code02_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 head) {
|
||||
System.out.print("in-order: ");
|
||||
if (head != null) {
|
||||
Stack<Node> stack = new Stack<Node>();
|
||||
while (!stack.isEmpty() || head != null) {
|
||||
if (head != null) {
|
||||
stack.push(head);
|
||||
head = head.left;
|
||||
} else {
|
||||
head = stack.pop();
|
||||
System.out.print(head.value + " ");
|
||||
head = head.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 class07;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
public class Code03_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,159 @@
|
||||
package class07;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
public class Code04_SerializeAndReconstructTree {
|
||||
|
||||
public static class Node {
|
||||
public int value;
|
||||
public Node left;
|
||||
public Node right;
|
||||
|
||||
public Node(int data) {
|
||||
this.value = data;
|
||||
}
|
||||
}
|
||||
|
||||
public static Queue<String> preSerial(Node head) {
|
||||
Queue<String> ans = new LinkedList<>();
|
||||
pres(head, ans);
|
||||
return ans;
|
||||
}
|
||||
|
||||
public static void pres(Node head, Queue<String> ans) {
|
||||
if (head == null) {
|
||||
ans.add(null);
|
||||
} else {
|
||||
ans.add(String.valueOf(head.value));
|
||||
pres(head.left, ans);
|
||||
pres(head.right, ans);
|
||||
}
|
||||
}
|
||||
|
||||
public static Node buildByPreQueue(Queue<String> prelist) {
|
||||
if (prelist == null || prelist.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
return preb(prelist);
|
||||
}
|
||||
|
||||
public static Node preb(Queue<String> prelist) {
|
||||
String value = prelist.poll();
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
Node head = new Node(Integer.valueOf(value));
|
||||
head.left = preb(prelist);
|
||||
head.right = preb(prelist);
|
||||
return head;
|
||||
}
|
||||
|
||||
public static Queue<String> levelSerial(Node head) {
|
||||
Queue<String> ans = new LinkedList<>();
|
||||
if (head == null) {
|
||||
ans.add(null);
|
||||
} else {
|
||||
ans.add(String.valueOf(head.value));
|
||||
Queue<Node> queue = new LinkedList<Node>();
|
||||
queue.add(head);
|
||||
while (!queue.isEmpty()) {
|
||||
head = queue.poll();
|
||||
if (head.left != null) {
|
||||
ans.add(String.valueOf(head.left.value));
|
||||
queue.add(head.left);
|
||||
} else {
|
||||
ans.add(null);
|
||||
}
|
||||
if (head.right != null) {
|
||||
ans.add(String.valueOf(head.right.value));
|
||||
queue.add(head.right);
|
||||
} else {
|
||||
ans.add(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
public static Node buildByLevelQueue(Queue<String> levelList) {
|
||||
if (levelList == null || levelList.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
Node head = generateNode(levelList.poll());
|
||||
Queue<Node> queue = new LinkedList<Node>();
|
||||
if (head != null) {
|
||||
queue.add(head);
|
||||
}
|
||||
Node node = null;
|
||||
while (!queue.isEmpty()) {
|
||||
node = queue.poll();
|
||||
node.left = generateNode(levelList.poll());
|
||||
node.right = generateNode(levelList.poll());
|
||||
if (node.left != null) {
|
||||
queue.add(node.left);
|
||||
}
|
||||
if (node.right != null) {
|
||||
queue.add(node.right);
|
||||
}
|
||||
}
|
||||
return head;
|
||||
}
|
||||
|
||||
public static Node generateNode(String val) {
|
||||
if (val == null) {
|
||||
return null;
|
||||
}
|
||||
return new Node(Integer.valueOf(val));
|
||||
}
|
||||
|
||||
// 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 boolean isSameValueStructure(Node head1, Node head2) {
|
||||
if (head1 == null && head2 != null) {
|
||||
return false;
|
||||
}
|
||||
if (head1 != null && head2 == null) {
|
||||
return false;
|
||||
}
|
||||
if (head1 == null && head2 == null) {
|
||||
return true;
|
||||
}
|
||||
if (head1.value != head2.value) {
|
||||
return false;
|
||||
}
|
||||
return isSameValueStructure(head1.left, head2.left) && isSameValueStructure(head1.right, head2.right);
|
||||
}
|
||||
|
||||
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);
|
||||
Queue<String> pre = preSerial(head);
|
||||
Queue<String> level = levelSerial(head);
|
||||
Node preBuild = buildByPreQueue(pre);
|
||||
Node levelBuild = buildByLevelQueue(level);
|
||||
if (!isSameValueStructure(preBuild, levelBuild)) {
|
||||
System.out.println("Oops!");
|
||||
}
|
||||
}
|
||||
System.out.println("finish!");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,74 @@
|
||||
package class07;
|
||||
|
||||
public class Code05_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 class07;
|
||||
|
||||
public class Code07_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,96 @@
|
||||
package class08;
|
||||
|
||||
public class Code02_IsFull {
|
||||
|
||||
public static class Node {
|
||||
public int value;
|
||||
public Node left;
|
||||
public Node right;
|
||||
|
||||
public Node(int data) {
|
||||
this.value = data;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isFull1(Node head) {
|
||||
if (head == null) {
|
||||
return true;
|
||||
}
|
||||
int height = h(head);
|
||||
int nodes = n(head);
|
||||
return (1 << height) - 1 == nodes;
|
||||
}
|
||||
|
||||
public static int h(Node head) {
|
||||
if (head == null) {
|
||||
return 0;
|
||||
}
|
||||
return Math.max(h(head.left), h(head.right)) + 1;
|
||||
}
|
||||
|
||||
public static int n(Node head) {
|
||||
if (head == null) {
|
||||
return 0;
|
||||
}
|
||||
return n(head.left) + n(head.right) + 1;
|
||||
}
|
||||
|
||||
public static boolean isFull2(Node head) {
|
||||
if (head == null) {
|
||||
return true;
|
||||
}
|
||||
Info all = process(head);
|
||||
return (1 << all.height) - 1 == all.nodes;
|
||||
}
|
||||
|
||||
public static class Info {
|
||||
public int height;
|
||||
public int nodes;
|
||||
|
||||
public Info(int h, int n) {
|
||||
height = h;
|
||||
nodes = n;
|
||||
}
|
||||
}
|
||||
|
||||
public static Info process(Node head) {
|
||||
if (head == null) {
|
||||
return new Info(0, 0);
|
||||
}
|
||||
Info leftInfo = process(head.left);
|
||||
Info rightInfo = process(head.right);
|
||||
int height = Math.max(leftInfo.height, rightInfo.height) + 1;
|
||||
int nodes = leftInfo.nodes + rightInfo.nodes + 1;
|
||||
return new Info(height, nodes);
|
||||
}
|
||||
|
||||
// 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 (isFull1(head) != isFull2(head)) {
|
||||
System.out.println("Oops!");
|
||||
}
|
||||
}
|
||||
System.out.println("finish!");
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,115 @@
|
||||
package class08;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Code03_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 {
|
||||
boolean isBST;
|
||||
public int min;
|
||||
public int max;
|
||||
|
||||
public Info(boolean is, int mi, int ma) {
|
||||
isBST = is;
|
||||
min = mi;
|
||||
max = ma;
|
||||
}
|
||||
}
|
||||
|
||||
public static Info process(Node head) {
|
||||
if (head == null) {
|
||||
return null;
|
||||
}
|
||||
Info leftInfo = process(head.left);
|
||||
Info rightInfo = process(head.right);
|
||||
int min = head.value;
|
||||
int max = head.value;
|
||||
if (leftInfo != null) {
|
||||
min = Math.min(min, leftInfo.min);
|
||||
max = Math.max(max, leftInfo.max);
|
||||
}
|
||||
if (rightInfo != null) {
|
||||
min = Math.min(min, rightInfo.min);
|
||||
max = Math.max(max, rightInfo.max);
|
||||
}
|
||||
boolean isBST = false;
|
||||
if (
|
||||
(leftInfo == null ? true : (leftInfo.isBST && leftInfo.max < head.value))
|
||||
&&
|
||||
(rightInfo == null ? true : (rightInfo.isBST && rightInfo.min > head.value))
|
||||
) {
|
||||
isBST = true;
|
||||
}
|
||||
return new Info(isBST, 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 (isBST1(head) != isBST2(head)) {
|
||||
System.out.println("Oops!");
|
||||
}
|
||||
}
|
||||
System.out.println("finish!");
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,229 @@
|
||||
package class08;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Code04_MaxSubBSTSize {
|
||||
|
||||
public static class Node {
|
||||
public int value;
|
||||
public Node left;
|
||||
public Node right;
|
||||
|
||||
public Node(int data) {
|
||||
this.value = data;
|
||||
}
|
||||
}
|
||||
|
||||
public static int getBSTSize(Node head) {
|
||||
if (head == null) {
|
||||
return 0;
|
||||
}
|
||||
ArrayList<Node> arr = new ArrayList<>();
|
||||
in(head, arr);
|
||||
for (int i = 1; i < arr.size(); i++) {
|
||||
if (arr.get(i).value <= arr.get(i - 1).value) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return arr.size();
|
||||
}
|
||||
|
||||
public static void in(Node head, ArrayList<Node> arr) {
|
||||
if (head == null) {
|
||||
return;
|
||||
}
|
||||
in(head.left, arr);
|
||||
arr.add(head);
|
||||
in(head.right, arr);
|
||||
}
|
||||
|
||||
public static int maxSubBSTSize1(Node head) {
|
||||
if (head == null) {
|
||||
return 0;
|
||||
}
|
||||
int h = getBSTSize(head);
|
||||
if (h != 0) {
|
||||
return h;
|
||||
}
|
||||
return Math.max(maxSubBSTSize1(head.left), maxSubBSTSize1(head.right));
|
||||
}
|
||||
|
||||
public static int maxSubBSTSize2(Node head) {
|
||||
if (head == null) {
|
||||
return 0;
|
||||
}
|
||||
return process(head).maxSubBSTSize;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// public static Info process(Node head) {
|
||||
// if (head == null) {
|
||||
// return null;
|
||||
// }
|
||||
// Info leftInfo = process(head.left);
|
||||
// Info rightInfo = process(head.right);
|
||||
// int min = head.value;
|
||||
// int max = head.value;
|
||||
// int maxSubBSTSize = 0;
|
||||
// if (leftInfo != null) {
|
||||
// min = Math.min(min, leftInfo.min);
|
||||
// max = Math.max(max, leftInfo.max);
|
||||
// maxSubBSTSize = Math.max(maxSubBSTSize, leftInfo.maxSubBSTSize);
|
||||
// }
|
||||
// if (rightInfo != null) {
|
||||
// min = Math.min(min, rightInfo.min);
|
||||
// max = Math.max(max, rightInfo.max);
|
||||
// maxSubBSTSize = Math.max(maxSubBSTSize, rightInfo.maxSubBSTSize);
|
||||
// }
|
||||
// boolean isBST = false;
|
||||
// if ((leftInfo == null ? true : (leftInfo.isAllBST && leftInfo.max < head.value))
|
||||
// && (rightInfo == null ? true : (rightInfo.isAllBST && rightInfo.min > head.value))) {
|
||||
// isBST = true;
|
||||
// maxSubBSTSize = (leftInfo == null ? 0 : leftInfo.maxSubBSTSize)
|
||||
// + (rightInfo == null ? 0 : rightInfo.maxSubBSTSize) + 1;
|
||||
// }
|
||||
// return new Info(isBST, maxSubBSTSize, min, max);
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 任何子树
|
||||
public static class Info {
|
||||
public boolean isAllBST;
|
||||
public int maxSubBSTSize;
|
||||
public int min;
|
||||
public int max;
|
||||
|
||||
public Info(boolean is, int size, int mi, int ma) {
|
||||
isAllBST = is;
|
||||
maxSubBSTSize = size;
|
||||
min = mi;
|
||||
max = ma;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static Info process(Node X) {
|
||||
if(X == null) {
|
||||
return null;
|
||||
}
|
||||
Info leftInfo = process(X.left);
|
||||
Info rightInfo = process(X.right);
|
||||
|
||||
|
||||
|
||||
int min = X.value;
|
||||
int max = X.value;
|
||||
|
||||
if(leftInfo != null) {
|
||||
min = Math.min(min, leftInfo.min);
|
||||
max = Math.max(max, leftInfo.max);
|
||||
}
|
||||
if(rightInfo != null) {
|
||||
min = Math.min(min, rightInfo.min);
|
||||
max = Math.max(max, rightInfo.max);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int maxSubBSTSize = 0;
|
||||
if(leftInfo != null) {
|
||||
maxSubBSTSize = leftInfo.maxSubBSTSize;
|
||||
}
|
||||
if(rightInfo !=null) {
|
||||
maxSubBSTSize = Math.max(maxSubBSTSize, rightInfo.maxSubBSTSize);
|
||||
}
|
||||
boolean isAllBST = false;
|
||||
|
||||
|
||||
if(
|
||||
// 左树整体需要是搜索二叉树
|
||||
( leftInfo == null ? true : leftInfo.isAllBST )
|
||||
&&
|
||||
( rightInfo == null ? true : rightInfo.isAllBST )
|
||||
&&
|
||||
// 左树最大值<x
|
||||
(leftInfo == null ? true : leftInfo.max < X.value)
|
||||
&&
|
||||
(rightInfo == null ? true : rightInfo.min > X.value)
|
||||
|
||||
|
||||
) {
|
||||
|
||||
maxSubBSTSize =
|
||||
(leftInfo == null ? 0 : leftInfo.maxSubBSTSize)
|
||||
+
|
||||
(rightInfo == null ? 0 : rightInfo.maxSubBSTSize)
|
||||
+
|
||||
1;
|
||||
isAllBST = true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return new Info(isAllBST, maxSubBSTSize, min, max);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// for test
|
||||
public static Node generateRandomBST(int maxLevel, int maxValue) {
|
||||
return generate(1, maxLevel, maxValue);
|
||||
}
|
||||
|
||||
// for test
|
||||
public static Node generate(int level, int maxLevel, int maxValue) {
|
||||
if (level > maxLevel || Math.random() < 0.5) {
|
||||
return null;
|
||||
}
|
||||
Node head = new Node((int) (Math.random() * maxValue));
|
||||
head.left = generate(level + 1, maxLevel, maxValue);
|
||||
head.right = generate(level + 1, maxLevel, maxValue);
|
||||
return head;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int maxLevel = 4;
|
||||
int maxValue = 100;
|
||||
int testTimes = 1000000;
|
||||
for (int i = 0; i < testTimes; i++) {
|
||||
Node head = generateRandomBST(maxLevel, maxValue);
|
||||
if (maxSubBSTSize1(head) != maxSubBSTSize2(head)) {
|
||||
System.out.println("Oops!");
|
||||
}
|
||||
}
|
||||
System.out.println("finish!");
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,135 @@
|
||||
package class08;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Code05_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 head) {
|
||||
if (head == null) {
|
||||
return null;
|
||||
}
|
||||
Info leftInfo = process(head.left);
|
||||
Info rightInfo = process(head.right);
|
||||
int min = head.value;
|
||||
int max = head.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 == head.left && leftInfo.max < head.value))
|
||||
&& (rightInfo == null ? true : (rightInfo.maxSubBSTHead == head.right && rightInfo.min > head.value))) {
|
||||
maxSubBSTHead = head;
|
||||
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,124 @@
|
||||
package class08;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
public class Code06_IsCBT {
|
||||
|
||||
public static class Node {
|
||||
public int value;
|
||||
public Node left;
|
||||
public Node right;
|
||||
|
||||
public Node(int data) {
|
||||
this.value = data;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isCBT1(Node head) {
|
||||
if (head == null) {
|
||||
return true;
|
||||
}
|
||||
LinkedList<Node> queue = new LinkedList<>();
|
||||
// 是否遇到过左右两个孩子不双全的节点
|
||||
boolean leaf = false;
|
||||
Node l = null;
|
||||
Node r = null;
|
||||
queue.add(head);
|
||||
while (!queue.isEmpty()) {
|
||||
head = queue.poll();
|
||||
l = head.left;
|
||||
r = head.right;
|
||||
if (
|
||||
// 如果遇到了不双全的节点之后,又发现当前节点不是叶节点
|
||||
(leaf && !(l == null && r == null)) || (l == null && r != null)) {
|
||||
return false;
|
||||
}
|
||||
if (l != null) {
|
||||
queue.add(l);
|
||||
}
|
||||
if (r != null) {
|
||||
queue.add(r);
|
||||
}
|
||||
if (l == null || r == null) {
|
||||
leaf = true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean isCBT2(Node head) {
|
||||
if (head == null) {
|
||||
return true;
|
||||
}
|
||||
return process(head).isCBT;
|
||||
}
|
||||
|
||||
public static class Info {
|
||||
public boolean isFull;
|
||||
public boolean isCBT;
|
||||
public int height;
|
||||
|
||||
public Info(boolean full, boolean cbt, int h) {
|
||||
isFull = full;
|
||||
isCBT = cbt;
|
||||
height = h;
|
||||
}
|
||||
}
|
||||
|
||||
public static Info process(Node head) {
|
||||
if (head == null) {
|
||||
return new Info(true, true, 0);
|
||||
}
|
||||
Info leftInfo = process(head.left);
|
||||
Info rightInfo = process(head.right);
|
||||
int height = Math.max(leftInfo.height, rightInfo.height) + 1;
|
||||
boolean isFull = leftInfo.isFull && rightInfo.isFull && leftInfo.height == rightInfo.height;
|
||||
boolean isCBT = false;
|
||||
if (isFull) {
|
||||
isCBT = true;
|
||||
} else {
|
||||
if (leftInfo.isCBT && rightInfo.isCBT) {
|
||||
if (leftInfo.isCBT && rightInfo.isFull && leftInfo.height == rightInfo.height + 1) {
|
||||
isCBT = true;
|
||||
}
|
||||
if (leftInfo.isFull && rightInfo.isFull && leftInfo.height == rightInfo.height + 1) {
|
||||
isCBT = true;
|
||||
}
|
||||
if (leftInfo.isFull && rightInfo.isCBT && leftInfo.height == rightInfo.height) {
|
||||
isCBT = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new Info(isFull, isCBT, height);
|
||||
}
|
||||
|
||||
// for test
|
||||
public static Node generateRandomBST(int maxLevel, int maxValue) {
|
||||
return generate(1, maxLevel, maxValue);
|
||||
}
|
||||
|
||||
// for test
|
||||
public static Node generate(int level, int maxLevel, int maxValue) {
|
||||
if (level > maxLevel || Math.random() < 0.5) {
|
||||
return null;
|
||||
}
|
||||
Node head = new Node((int) (Math.random() * maxValue));
|
||||
head.left = generate(level + 1, maxLevel, maxValue);
|
||||
head.right = generate(level + 1, maxLevel, maxValue);
|
||||
return head;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int maxLevel = 5;
|
||||
int maxValue = 100;
|
||||
int testTimes = 1000000;
|
||||
for (int i = 0; i < testTimes; i++) {
|
||||
Node head = generateRandomBST(maxLevel, maxValue);
|
||||
if (isCBT1(head) != isCBT2(head)) {
|
||||
System.out.println("Oops!");
|
||||
}
|
||||
}
|
||||
System.out.println("finish!");
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,143 @@
|
||||
package class08;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class Code07_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;
|
||||
}
|
||||
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 o1, Node o2) {
|
||||
return process(head, o1, o2).ans;
|
||||
}
|
||||
|
||||
public static class Info {
|
||||
public Node ans;
|
||||
public boolean findO1;
|
||||
public boolean findO2;
|
||||
|
||||
public Info(Node a, boolean f1, boolean f2) {
|
||||
ans = a;
|
||||
findO1 = f1;
|
||||
findO2 = f2;
|
||||
}
|
||||
}
|
||||
|
||||
public static Info process(Node head, Node o1, Node o2) {
|
||||
if (head == null) {
|
||||
return new Info(null, false, false);
|
||||
}
|
||||
Info leftInfo = process(head.left, o1, o2);
|
||||
Info rightInfo = process(head.right, o1, o2);
|
||||
|
||||
boolean findO1 = head == o1 || leftInfo.findO1 || rightInfo.findO1;
|
||||
boolean findO2 = head == o2 || leftInfo.findO2 || rightInfo.findO2;
|
||||
Node ans = null;
|
||||
if (leftInfo.ans != null) {
|
||||
ans = leftInfo.ans;
|
||||
}
|
||||
if (rightInfo.ans != null) {
|
||||
ans = rightInfo.ans;
|
||||
}
|
||||
if (ans == null) {
|
||||
if (findO1 && findO2) {
|
||||
ans = head;
|
||||
}
|
||||
}
|
||||
return new Info(ans, findO1, findO2);
|
||||
}
|
||||
|
||||
// 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,151 @@
|
||||
package class08;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class Code08_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);
|
||||
}
|
||||
|
||||
// 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,113 @@
|
||||
package class08;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Code09_MaxHappy {
|
||||
|
||||
public static class Employee {
|
||||
public int happy;
|
||||
public List<Employee> nexts;
|
||||
|
||||
public Employee(int h) {
|
||||
happy = h;
|
||||
nexts = new ArrayList<>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static int maxHappy1(Employee boss) {
|
||||
if (boss == null) {
|
||||
return 0;
|
||||
}
|
||||
return process1(boss, false);
|
||||
}
|
||||
|
||||
public static int process1(Employee cur, boolean up) {
|
||||
if (up) {
|
||||
int ans = 0;
|
||||
for (Employee next : cur.nexts) {
|
||||
ans += process1(next, false);
|
||||
}
|
||||
return ans;
|
||||
} else {
|
||||
int p1 = cur.happy;
|
||||
int p2 = 0;
|
||||
for (Employee next : cur.nexts) {
|
||||
p1 += process1(next, true);
|
||||
p2 += process1(next, false);
|
||||
}
|
||||
return Math.max(p1, p2);
|
||||
}
|
||||
}
|
||||
|
||||
public static int maxHappy2(Employee boss) {
|
||||
if (boss == null) {
|
||||
return 0;
|
||||
}
|
||||
Info all = process2(boss);
|
||||
return Math.max(all.yes, all.no);
|
||||
}
|
||||
|
||||
public static class Info {
|
||||
public int yes;
|
||||
public int no;
|
||||
|
||||
public Info(int y, int n) {
|
||||
yes = y;
|
||||
no = n;
|
||||
}
|
||||
}
|
||||
|
||||
public static Info process2(Employee x) {
|
||||
if (x.nexts.isEmpty()) {
|
||||
return new Info(x.happy, 0);
|
||||
}
|
||||
int yes = x.happy;
|
||||
int no = 0;
|
||||
for (Employee next : x.nexts) {
|
||||
Info nextInfo = process2(next);
|
||||
yes += nextInfo.no;
|
||||
no += Math.max(nextInfo.yes, nextInfo.no);
|
||||
}
|
||||
return new Info(yes, no);
|
||||
}
|
||||
|
||||
// for test
|
||||
public static Employee genarateBoss(int maxLevel, int maxNexts, int maxHappy) {
|
||||
if (Math.random() < 0.02) {
|
||||
return null;
|
||||
}
|
||||
Employee boss = new Employee((int) (Math.random() * (maxHappy + 1)));
|
||||
genarateNexts(boss, 1, maxLevel, maxNexts, maxHappy);
|
||||
return boss;
|
||||
}
|
||||
|
||||
// for test
|
||||
public static void genarateNexts(Employee e, int level, int maxLevel, int maxNexts, int maxHappy) {
|
||||
if (level > maxLevel) {
|
||||
return;
|
||||
}
|
||||
int nextsSize = (int) (Math.random() * (maxNexts + 1));
|
||||
for (int i = 0; i < nextsSize; i++) {
|
||||
Employee next = new Employee((int) (Math.random() * (maxHappy + 1)));
|
||||
e.nexts.add(next);
|
||||
genarateNexts(next, level + 1, maxLevel, maxNexts, maxHappy);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int maxLevel = 4;
|
||||
int maxNexts = 7;
|
||||
int maxHappy = 100;
|
||||
int testTimes = 100000;
|
||||
for (int i = 0; i < testTimes; i++) {
|
||||
Employee boss = genarateBoss(maxLevel, maxNexts, maxHappy);
|
||||
if (maxHappy1(boss) != maxHappy2(boss)) {
|
||||
System.out.println("Oops!");
|
||||
}
|
||||
}
|
||||
System.out.println("finish!");
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,101 @@
|
||||
package class09;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class Code01_LowestLexicography {
|
||||
|
||||
public static String lowestString1(String[] strs) {
|
||||
if (strs == null || strs.length == 0) {
|
||||
return "";
|
||||
}
|
||||
ArrayList<String> all = new ArrayList<>();
|
||||
HashSet<Integer> use = new HashSet<>();
|
||||
process(strs, use, "", all);
|
||||
String lowest = all.get(0);
|
||||
for (int i = 1; i < all.size(); i++) {
|
||||
if (all.get(i).compareTo(lowest) < 0) {
|
||||
lowest = all.get(i);
|
||||
}
|
||||
}
|
||||
return lowest;
|
||||
}
|
||||
|
||||
public static void process(String[] strs, HashSet<Integer> use, String path, ArrayList<String> all) {
|
||||
if (use.size() == strs.length) {
|
||||
all.add(path);
|
||||
} else {
|
||||
for (int i = 0; i < strs.length; i++) {
|
||||
if (!use.contains(i)) {
|
||||
use.add(i);
|
||||
process(strs, use, path + strs[i], all);
|
||||
use.remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class MyComparator implements Comparator<String> {
|
||||
@Override
|
||||
public int compare(String a, String b) {
|
||||
return (a + b).compareTo(b + a);
|
||||
}
|
||||
}
|
||||
|
||||
public static String lowestString2(String[] strs) {
|
||||
if (strs == null || strs.length == 0) {
|
||||
return "";
|
||||
}
|
||||
Arrays.sort(strs, new MyComparator());
|
||||
String res = "";
|
||||
for (int i = 0; i < strs.length; i++) {
|
||||
res += strs[i];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// for test
|
||||
public static String generateRandomString(int strLen) {
|
||||
char[] ans = new char[(int) (Math.random() * strLen) + 1];
|
||||
for (int i = 0; i < ans.length; i++) {
|
||||
int value = (int) (Math.random() * 5);
|
||||
ans[i] = (char) (97 + value);
|
||||
}
|
||||
return String.valueOf(ans);
|
||||
}
|
||||
|
||||
// for test
|
||||
public static String[] generateRandomStringArray(int arrLen, int strLen) {
|
||||
String[] ans = new String[(int) (Math.random() * arrLen) + 1];
|
||||
for (int i = 0; i < ans.length; i++) {
|
||||
ans[i] = generateRandomString(strLen);
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
// for test
|
||||
public static String[] copyStringArray(String[] arr) {
|
||||
String[] ans = new String[arr.length];
|
||||
for (int i = 0; i < ans.length; i++) {
|
||||
ans[i] = String.valueOf(arr[i]);
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int arrLen = 6;
|
||||
int strLen = 5;
|
||||
int testTimes = 100000;
|
||||
for (int i = 0; i < testTimes; i++) {
|
||||
String[] arr1 = generateRandomStringArray(arrLen, strLen);
|
||||
String[] arr2 = copyStringArray(arr1);
|
||||
if (!lowestString1(arr1).equals(lowestString2(arr2))) {
|
||||
System.out.println("Oops!");
|
||||
}
|
||||
}
|
||||
System.out.println("finish!");
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,81 @@
|
||||
package class09;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
public class Code02_Light {
|
||||
|
||||
public static int minLight1(String road) {
|
||||
if (road == null || road.length() == 0) {
|
||||
return 0;
|
||||
}
|
||||
return process(road.toCharArray(), 0, new HashSet<>());
|
||||
}
|
||||
|
||||
public static int process(char[] str, int index, HashSet<Integer> lights) {
|
||||
if (index == str.length) {
|
||||
for (int i = 0; i < str.length; i++) {
|
||||
if (str[i] != 'X') {
|
||||
if (!lights.contains(i - 1) && !lights.contains(i) && !lights.contains(i + 1)) {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return lights.size();
|
||||
} else {
|
||||
int no = process(str, index + 1, lights);
|
||||
int yes = Integer.MAX_VALUE;
|
||||
if (str[index] == '.') {
|
||||
lights.add(index);
|
||||
yes = process(str, index + 1, lights);
|
||||
lights.remove(index);
|
||||
}
|
||||
return Math.min(no, yes);
|
||||
}
|
||||
}
|
||||
|
||||
public static int minLight2(String road) {
|
||||
char[] str = road.toCharArray();
|
||||
int index = 0;
|
||||
int light = 0;
|
||||
while (index < str.length) {
|
||||
if (str[index] == 'X') {
|
||||
index++;
|
||||
} else {
|
||||
light++;
|
||||
if (index + 1 == str.length) {
|
||||
break;
|
||||
} else {
|
||||
if (str[index + 1] == 'X') {
|
||||
index = index + 2;
|
||||
} else {
|
||||
index = index + 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return light;
|
||||
}
|
||||
|
||||
// for test
|
||||
public static String randomString(int len) {
|
||||
char[] res = new char[(int) (Math.random() * len) + 1];
|
||||
for (int i = 0; i < res.length; i++) {
|
||||
res[i] = Math.random() < 0.5 ? 'X' : '.';
|
||||
}
|
||||
return String.valueOf(res);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int len = 20;
|
||||
int testTime = 100000;
|
||||
for (int i = 0; i < testTime; i++) {
|
||||
String test = randomString(len);
|
||||
int ans1 = minLight1(test);
|
||||
int ans2 = minLight2(test);
|
||||
if (ans1 != ans2) {
|
||||
System.out.println("oops!");
|
||||
}
|
||||
}
|
||||
System.out.println("finish!");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,76 @@
|
||||
package class09;
|
||||
|
||||
import java.util.PriorityQueue;
|
||||
|
||||
public class Code03_LessMoneySplitGold {
|
||||
|
||||
public static int lessMoney1(int[] arr) {
|
||||
if (arr == null || arr.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
return process(arr, 0);
|
||||
}
|
||||
|
||||
public static int process(int[] arr, int pre) {
|
||||
if (arr.length == 1) {
|
||||
return pre;
|
||||
}
|
||||
int ans = Integer.MAX_VALUE;
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
for (int j = i + 1; j < arr.length; j++) {
|
||||
ans = Math.min(ans, process(copyAndMergeTwo(arr, i, j), pre + arr[i] + arr[j]));
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
public static int[] copyAndMergeTwo(int[] arr, int i, int j) {
|
||||
int[] ans = new int[arr.length - 1];
|
||||
int ansi = 0;
|
||||
for (int arri = 0; arri < arr.length; arri++) {
|
||||
if (arri != i && arri != j) {
|
||||
ans[ansi++] = arr[arri];
|
||||
}
|
||||
}
|
||||
ans[ansi] = arr[i] + arr[j];
|
||||
return ans;
|
||||
}
|
||||
|
||||
public static int lessMoney2(int[] arr) {
|
||||
PriorityQueue<Integer> pQ = new PriorityQueue<>();
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
pQ.add(arr[i]);
|
||||
}
|
||||
int sum = 0;
|
||||
int cur = 0;
|
||||
while (pQ.size() > 1) {
|
||||
cur = pQ.poll() + pQ.poll();
|
||||
sum += cur;
|
||||
pQ.add(cur);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
// 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) (Math.random() * (maxValue + 1));
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int testTime = 100000;
|
||||
int maxSize = 6;
|
||||
int maxValue = 1000;
|
||||
for (int i = 0; i < testTime; i++) {
|
||||
int[] arr = generateRandomArray(maxSize, maxValue);
|
||||
if (lessMoney1(arr) != lessMoney2(arr)) {
|
||||
System.out.println("Oops!");
|
||||
}
|
||||
}
|
||||
System.out.println("finish!");
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,100 @@
|
||||
package class09;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
|
||||
public class Code04_BestArrange {
|
||||
|
||||
public static class Program {
|
||||
public int start;
|
||||
public int end;
|
||||
|
||||
public Program(int start, int end) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
}
|
||||
|
||||
public static int bestArrange1(Program[] programs) {
|
||||
if (programs == null || programs.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
return process(programs, 0, 0);
|
||||
}
|
||||
|
||||
public static int process(Program[] programs, int done, int timeLine) {
|
||||
if (programs.length == 0) {
|
||||
return done;
|
||||
}
|
||||
int max = done;
|
||||
for (int i = 0; i < programs.length; i++) {
|
||||
if (programs[i].start >= timeLine) {
|
||||
Program[] next = copyButExcept(programs, i);
|
||||
max = Math.max(max, process(next, done + 1, programs[i].end));
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
public static Program[] copyButExcept(Program[] programs, int i) {
|
||||
Program[] ans = new Program[programs.length - 1];
|
||||
int index = 0;
|
||||
for (int k = 0; k < programs.length; k++) {
|
||||
if (k != i) {
|
||||
ans[index++] = programs[k];
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
public static int bestArrange2(Program[] programs) {
|
||||
Arrays.sort(programs, new ProgramComparator());
|
||||
int timeLine = 0;
|
||||
int result = 0;
|
||||
for (int i = 0; i < programs.length; i++) {
|
||||
if (timeLine <= programs[i].start) {
|
||||
result++;
|
||||
timeLine = programs[i].end;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static class ProgramComparator implements Comparator<Program> {
|
||||
|
||||
@Override
|
||||
public int compare(Program o1, Program o2) {
|
||||
return o1.end - o2.end;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// for test
|
||||
public static Program[] generatePrograms(int programSize, int timeMax) {
|
||||
Program[] ans = new Program[(int) (Math.random() * (programSize + 1))];
|
||||
for (int i = 0; i < ans.length; i++) {
|
||||
int r1 = (int) (Math.random() * (timeMax + 1));
|
||||
int r2 = (int) (Math.random() * (timeMax + 1));
|
||||
if (r1 == r2) {
|
||||
ans[i] = new Program(r1, r1 + 1);
|
||||
} else {
|
||||
ans[i] = new Program(Math.min(r1, r2), Math.max(r1, r2));
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int programSize = 12;
|
||||
int timeMax = 20;
|
||||
int timeTimes = 1000000;
|
||||
for (int i = 0; i < timeTimes; i++) {
|
||||
Program[] programs = generatePrograms(programSize, timeMax);
|
||||
if (bestArrange1(programs) != bestArrange2(programs)) {
|
||||
System.out.println("Oops!");
|
||||
}
|
||||
}
|
||||
System.out.println("finish!");
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
package class09;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.PriorityQueue;
|
||||
|
||||
public class Code05_IPO {
|
||||
|
||||
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,73 @@
|
||||
package class10;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class Code01_UnionFind {
|
||||
|
||||
public static class Node<V> {
|
||||
V value;
|
||||
|
||||
public Node(V v) {
|
||||
value = v;
|
||||
}
|
||||
}
|
||||
|
||||
public static class UnionSet<V> {
|
||||
public HashMap<V, Node<V>> nodes;
|
||||
public HashMap<Node<V>, Node<V>> parents;
|
||||
public HashMap<Node<V>, Integer> sizeMap;
|
||||
|
||||
public UnionSet(List<V> values) {
|
||||
for (V value : values) {
|
||||
Node<V> node = new Node<>(value);
|
||||
nodes.put(value, 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);
|
||||
}
|
||||
// cur头节点
|
||||
while (!path.isEmpty()) {
|
||||
parents.put(path.pop(), cur);
|
||||
}
|
||||
return cur;
|
||||
}
|
||||
|
||||
public boolean isSameSet(V a, V b) {
|
||||
if (!nodes.containsKey(a) || !nodes.containsKey(b)) {
|
||||
return false;
|
||||
}
|
||||
return findFather(nodes.get(a)) == findFather(nodes.get(b));
|
||||
}
|
||||
|
||||
public void union(V a, V b) {
|
||||
if (!nodes.containsKey(a) || !nodes.containsKey(b)) {
|
||||
return;
|
||||
}
|
||||
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);
|
||||
if (aSetSize >= bSetSize) {
|
||||
parents.put(bHead, aHead);
|
||||
sizeMap.put(aHead, aSetSize + bSetSize);
|
||||
sizeMap.remove(bHead);
|
||||
} else {
|
||||
parents.put(aHead, bHead);
|
||||
sizeMap.put(bHead, aSetSize + bSetSize);
|
||||
sizeMap.remove(aHead);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
package class10;
|
||||
|
||||
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,142 @@
|
||||
package class10;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
|
||||
//undirected graph only
|
||||
public class Code04_Kruskal {
|
||||
|
||||
public static class MySets{
|
||||
public HashMap<Node, List<Node>> setMap;
|
||||
public MySets(List<Node> nodes) {
|
||||
for(Node cur : nodes) {
|
||||
List<Node> set = new ArrayList<Node>();
|
||||
set.add(cur);
|
||||
setMap.put(cur, set);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean isSameSet(Node from, Node to) {
|
||||
List<Node> fromSet = setMap.get(from);
|
||||
List<Node> toSet = setMap.get(to);
|
||||
return fromSet == toSet;
|
||||
}
|
||||
|
||||
|
||||
public void union(Node from, Node to) {
|
||||
List<Node> fromSet = setMap.get(from);
|
||||
List<Node> toSet = setMap.get(to);
|
||||
for(Node toNode : toSet) {
|
||||
fromSet.add(toNode);
|
||||
setMap.put(toNode, fromSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 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 class10;
|
||||
|
||||
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 class10;
|
||||
|
||||
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,19 @@
|
||||
package class10;
|
||||
|
||||
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,67 @@
|
||||
package class11;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
public class Code02_PrintAllSubsquences {
|
||||
|
||||
public static List<String> subs(String s) {
|
||||
char[] str = s.toCharArray();
|
||||
String path = "";
|
||||
List<String> ans = new ArrayList<>();
|
||||
process1(str, 0, ans, path);
|
||||
return ans;
|
||||
}
|
||||
|
||||
public static void process1(char[] str, int index, List<String> ans, String path) {
|
||||
if (index == str.length) {
|
||||
ans.add(path);
|
||||
return;
|
||||
}
|
||||
String no = path;
|
||||
process1(str, index + 1, ans, no);
|
||||
String yes = path + String.valueOf(str[index]);
|
||||
process1(str, index + 1, ans, yes);
|
||||
}
|
||||
|
||||
public static List<String> subsNoRepeat(String s) {
|
||||
char[] str = s.toCharArray();
|
||||
String path = "";
|
||||
HashSet<String> set = new HashSet<>();
|
||||
process2(str, 0, set, path);
|
||||
List<String> ans = new ArrayList<>();
|
||||
for (String cur : set) {
|
||||
ans.add(cur);
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
public static void process2(char[] str, int index, HashSet<String> set, String path) {
|
||||
if (index == str.length) {
|
||||
set.add(path);
|
||||
return;
|
||||
}
|
||||
String no = path;
|
||||
process2(str, index + 1, set, no);
|
||||
String yes = path + String.valueOf(str[index]);
|
||||
process2(str, index + 1, set, yes);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
String test = "aacc";
|
||||
List<String> ans1 = subs(test);
|
||||
List<String> ans2 = subsNoRepeat(test);
|
||||
|
||||
for (String str : ans1) {
|
||||
System.out.println(str);
|
||||
}
|
||||
System.out.println("=================");
|
||||
for (String str : ans2) {
|
||||
System.out.println(str);
|
||||
}
|
||||
System.out.println("=================");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,74 @@
|
||||
package class11;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Code03_PrintAllPermutations {
|
||||
|
||||
public static ArrayList<String> permutation(String str) {
|
||||
ArrayList<String> res = new ArrayList<>();
|
||||
if (str == null || str.length() == 0) {
|
||||
return res;
|
||||
}
|
||||
char[] chs = str.toCharArray();
|
||||
process(chs, 0, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
public static void process(char[] str, int i, ArrayList<String> res) {
|
||||
if (i == str.length) {
|
||||
res.add(String.valueOf(str));
|
||||
}
|
||||
for (int j = i; j < str.length; j++) {
|
||||
swap(str, i, j);
|
||||
process(str, i + 1, res);
|
||||
swap(str, i, j);
|
||||
}
|
||||
}
|
||||
|
||||
public static ArrayList<String> permutationNoRepeat(String str) {
|
||||
ArrayList<String> res = new ArrayList<>();
|
||||
if (str == null || str.length() == 0) {
|
||||
return res;
|
||||
}
|
||||
char[] chs = str.toCharArray();
|
||||
process2(chs, 0, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
public static void process2(char[] str, int i, ArrayList<String> res) {
|
||||
if (i == str.length) {
|
||||
res.add(String.valueOf(str));
|
||||
}
|
||||
boolean[] visit = new boolean[26]; // visit[0 1 .. 25]
|
||||
for (int j = i; j < str.length; j++) {
|
||||
if (!visit[str[j] - 'a']) {
|
||||
visit[str[j] - 'a'] = true;
|
||||
swap(str, i, j);
|
||||
process2(str, i + 1, res);
|
||||
swap(str, i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 = "aac";
|
||||
List<String> ans1 = permutation(s);
|
||||
for (String str : ans1) {
|
||||
System.out.println(str);
|
||||
}
|
||||
System.out.println("=======");
|
||||
List<String> ans2 = permutationNoRepeat(s);
|
||||
for (String str : ans2) {
|
||||
System.out.println(str);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
package class11;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
public class Code04_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,49 @@
|
||||
package class11;
|
||||
|
||||
public class Code08_CardsInLine {
|
||||
|
||||
public static int win1(int[] arr) {
|
||||
if (arr == null || arr.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
return Math.max(f(arr, 0, arr.length - 1), s(arr, 0, arr.length - 1));
|
||||
}
|
||||
|
||||
public static int f(int[] arr, int i, int j) {
|
||||
if (i == j) {
|
||||
return arr[i];
|
||||
}
|
||||
return Math.max(arr[i] + s(arr, i + 1, j), arr[j] + s(arr, i, j - 1));
|
||||
}
|
||||
|
||||
public static int s(int[] arr, int i, int j) {
|
||||
if (i == j) {
|
||||
return 0;
|
||||
}
|
||||
return Math.min(f(arr, i + 1, j), f(arr, i, j - 1));
|
||||
}
|
||||
|
||||
public static int win2(int[] arr) {
|
||||
if (arr == null || arr.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
int[][] f = new int[arr.length][arr.length];
|
||||
int[][] s = new int[arr.length][arr.length];
|
||||
for (int j = 0; j < arr.length; j++) {
|
||||
f[j][j] = arr[j];
|
||||
for (int i = j - 1; i >= 0; i--) {
|
||||
f[i][j] = Math.max(arr[i] + s[i + 1][j], arr[j] + s[i][j - 1]);
|
||||
s[i][j] = Math.min(f[i + 1][j], f[i][j - 1]);
|
||||
}
|
||||
}
|
||||
return Math.max(f[0][arr.length - 1], s[0][arr.length - 1]);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int[] arr = { 1, 9, 1 };
|
||||
System.out.println(win1(arr));
|
||||
System.out.println(win2(arr));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,61 @@
|
||||
package class12;
|
||||
|
||||
public class Code04_CardsInLine {
|
||||
|
||||
public static int win1(int[] arr) {
|
||||
if (arr == null || arr.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
return Math.max(f(arr, 0, arr.length - 1), s(arr, 0, arr.length - 1));
|
||||
}
|
||||
|
||||
public static int f(int[] arr, int L, int R) {
|
||||
if (L == R) {
|
||||
return arr[L];
|
||||
}
|
||||
return Math.max(arr[L] + s(arr, L + 1, R), arr[R] + s(arr, L, R - 1));
|
||||
}
|
||||
|
||||
public static int s(int[] arr, int L, int R) {
|
||||
if (L == R) {
|
||||
return 0;
|
||||
}
|
||||
return Math.min(f(arr, L + 1, R), f(arr, L, R - 1));
|
||||
}
|
||||
|
||||
public static int windp(int[] arr) {
|
||||
if (arr == null || arr.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
int N = arr.length;
|
||||
int[][] f = new int[N][N];
|
||||
int[][] s = new int[N][N];
|
||||
for (int i = 0; i < N; i++) {
|
||||
f[i][i] = arr[i];
|
||||
}
|
||||
// 0,0 右下方移动
|
||||
// 0,1
|
||||
// 0,2
|
||||
// 0,N-1
|
||||
for (int col = 1; col < N; col++) {
|
||||
// 对角线出发位置(0,col)
|
||||
int L = 0;
|
||||
int R = col;
|
||||
while (L < N && R < N) {
|
||||
f[L][R] = Math.max(arr[L] + s[L + 1][R], arr[R] + s[L][R - 1]);
|
||||
s[L][R] = Math.min(f[L + 1][R], f[L][R - 1]);
|
||||
L++;
|
||||
R++;
|
||||
}
|
||||
}
|
||||
return Math.max(f[0][N - 1], s[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(windp(arr));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
package class12;
|
||||
|
||||
public class Code05_PalindromeSubsequence {
|
||||
|
||||
public static int lcse(char[] str1, char[] str2) {
|
||||
int[][] dp = new int[str1.length][str2.length];
|
||||
dp[0][0] = str1[0] == str2[0] ? 1 : 0;
|
||||
for (int i = 1; i < str1.length; i++) {
|
||||
dp[i][0] = Math.max(dp[i - 1][0], str1[i] == str2[0] ? 1 : 0);
|
||||
}
|
||||
for (int j = 1; j < str2.length; j++) {
|
||||
dp[0][j] = Math.max(dp[0][j - 1], str1[0] == str2[j] ? 1 : 0);
|
||||
}
|
||||
for (int i = 1; i < str1.length; i++) {
|
||||
for (int j = 1; j < str2.length; j++) {
|
||||
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
|
||||
if (str1[i] == str2[j]) {
|
||||
dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - 1] + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return dp[str1.length - 1][str2.length - 1];
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in new issue