└── src ├── class06 ├── Code04_MaximumDepthOfBinaryTree.java ├── Code02_SameTree.java ├── Code03_SymmetricTree.java ├── Code01_MergeKSortedLists.java ├── TraversalBinaryTree.java ├── ShowComparator2.java ├── Code05_ConstructBinaryTreeFromPreorderAndInorderTraversal.java └── ShowComparator.java ├── class01 ├── Code02_SumOfFactorial.java ├── Code01_PrintBinary.java ├── Code03_Sort.java ├── Code05_BubbleSort.java ├── Code04_SelectionSort.java └── Code06_InsertionSort.java ├── class02 ├── Code01_PreSum.java ├── Code03_EqualProbabilityRandom.java ├── Code03_Comp.java └── Code02_RandToRand.java ├── class04 ├── Code06_MergeTwoSortedLinkedList.java ├── Code04_ReverseNodesInKGroup.java ├── Code05_AddTwoNumbers.java ├── Code03_DoubleLinkedListToDeque.java ├── Code02_LinkedListToQueueAndStack.java └── Code01_ReverseList.java ├── class08 ├── Code01_GetMax.java ├── Code02_MergeSort.java └── Code03_PartitionAndQuickSort.java ├── class07 ├── Code02_BalancedBinaryTree.java ├── Code01_BinaryTreeLevelOrderTraversalII.java ├── Code04_PathSumII.java ├── Code03_PathSum.java └── Code05_IsBinarySearchTree.java ├── class05 ├── Code02_BitMap2.java ├── Code01_BitMap1.java └── Code03_BitAddMinusMultiDiv.java └── class03 ├── Code01_BSExist.java ├── Code03_BSNearRight.java ├── Code02_BSNearLeft.java ├── Code04_BSAwesome.java └── Code05_HashMapTreeMap.java /src/class06/Code04_MaximumDepthOfBinaryTree.java: -------------------------------------------------------------------------------- 1 | package class06; 2 | 3 | // 测试链接:https://leetcode.com/problems/maximum-depth-of-binary-tree 4 | public class Code04_MaximumDepthOfBinaryTree { 5 | 6 | public static class TreeNode { 7 | public int val; 8 | public TreeNode left; 9 | public TreeNode right; 10 | } 11 | 12 | // 以root为头的树,最大高度是多少返回! 13 | public static int maxDepth(TreeNode root) { 14 | if (root == null) { 15 | return 0; 16 | } 17 | return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/class06/Code02_SameTree.java: -------------------------------------------------------------------------------- 1 | package class06; 2 | 3 | // 测试链接:https://leetcode.com/problems/same-tree 4 | public class Code02_SameTree { 5 | 6 | public static class TreeNode { 7 | public int val; 8 | public TreeNode left; 9 | public TreeNode right; 10 | } 11 | 12 | public static boolean isSameTree(TreeNode p, TreeNode q) { 13 | if (p == null ^ q == null) { 14 | return false; 15 | } 16 | if (p == null && q == null) { 17 | return true; 18 | } 19 | // 都不为空 20 | return p.val == q.val && isSameTree(p.left, q.left) && isSameTree(p.right, q.right); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/class06/Code03_SymmetricTree.java: -------------------------------------------------------------------------------- 1 | package class06; 2 | 3 | // 测试链接:https://leetcode.com/problems/symmetric-tree 4 | public class Code03_SymmetricTree { 5 | 6 | public static class TreeNode { 7 | public int val; 8 | public TreeNode left; 9 | public TreeNode right; 10 | } 11 | 12 | public static boolean isSymmetric(TreeNode root) { 13 | return isMirror(root, root); 14 | } 15 | 16 | public static boolean isMirror(TreeNode h1, TreeNode h2) { 17 | if (h1 == null ^ h2 == null) { 18 | return false; 19 | } 20 | if (h1 == null && h2 == null) { 21 | return true; 22 | } 23 | return h1.val == h2.val && isMirror(h1.left, h2.right) && isMirror(h1.right, h2.left); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/class01/Code02_SumOfFactorial.java: -------------------------------------------------------------------------------- 1 | package class01; 2 | 3 | public class Code02_SumOfFactorial { 4 | 5 | public static long f1(int N) { 6 | long ans = 0; 7 | for (int i = 1; i <= N; i++) { 8 | ans += factorial(i); 9 | } 10 | return ans; 11 | } 12 | 13 | public static long factorial(int N) { 14 | long ans = 1; 15 | for (int i = 1; i <= N; i++) { 16 | ans *= i; 17 | } 18 | return ans; 19 | } 20 | 21 | public static long f2(int N) { 22 | long ans = 0; 23 | long cur = 1; 24 | for (int i = 1; i <= N; i++) { 25 | cur = cur * i; 26 | ans += cur; 27 | } 28 | return ans; 29 | } 30 | 31 | public static void main(String[] args) { 32 | int N = 10; 33 | System.out.println(f1(N)); 34 | System.out.println(f2(N)); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/class02/Code01_PreSum.java: -------------------------------------------------------------------------------- 1 | package class02; 2 | 3 | public class Code01_PreSum { 4 | 5 | public static class RangeSum1 { 6 | 7 | private int[] arr; 8 | 9 | public RangeSum1(int[] array) { 10 | arr = array; 11 | } 12 | 13 | public int rangeSum(int L, int R) { 14 | int sum = 0; 15 | for (int i = L; i <= R; i++) { 16 | sum += arr[i]; 17 | } 18 | return sum; 19 | } 20 | 21 | } 22 | 23 | public static class RangeSum2 { 24 | 25 | private int[] preSum; 26 | 27 | public RangeSum2(int[] array) { 28 | int N = array.length; 29 | preSum = new int[N]; 30 | preSum[0] = array[0]; 31 | for (int i = 1; i < N; i++) { 32 | preSum[i] = preSum[i - 1] + array[i]; 33 | } 34 | } 35 | 36 | public int rangeSum(int L, int R) { 37 | return L == 0 ? preSum[R] : preSum[R] - preSum[L - 1]; 38 | } 39 | 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/class04/Code06_MergeTwoSortedLinkedList.java: -------------------------------------------------------------------------------- 1 | package class04; 2 | 3 | // 测试链接:https://leetcode.com/problems/merge-two-sorted-lists 4 | public class Code06_MergeTwoSortedLinkedList { 5 | 6 | // 不要提交这个类 7 | public static class ListNode { 8 | public int val; 9 | public ListNode next; 10 | } 11 | 12 | public static ListNode mergeTwoLists(ListNode head1, ListNode head2) { 13 | if (head1 == null || head2 == null) { 14 | return head1 == null ? head2 : head1; 15 | } 16 | ListNode head = head1.val <= head2.val ? head1 : head2; 17 | ListNode cur1 = head.next; 18 | ListNode cur2 = head == head1 ? head2 : head1; 19 | ListNode pre = head; 20 | while (cur1 != null && cur2 != null) { 21 | if (cur1.val <= cur2.val) { 22 | pre.next = cur1; 23 | cur1 = cur1.next; 24 | } else { 25 | pre.next = cur2; 26 | cur2 = cur2.next; 27 | } 28 | pre = pre.next; 29 | } 30 | pre.next = cur1 != null ? cur1 : cur2; 31 | return head; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/class08/Code01_GetMax.java: -------------------------------------------------------------------------------- 1 | package class08; 2 | 3 | public class Code01_GetMax { 4 | 5 | public static int flip(int n) { 6 | return n ^ 1; 7 | } 8 | 9 | public static int sign(int n) { 10 | return flip((n >> 31) & 1); 11 | } 12 | 13 | public static int getMax1(int a, int b) { 14 | int c = a - b; 15 | int scA = sign(c); 16 | int scB = flip(scA); 17 | return a * scA + b * scB; 18 | } 19 | 20 | public static int getMax2(int a, int b) { 21 | int c = a - b; 22 | int sa = sign(a); 23 | int sb = sign(b); 24 | int sc = sign(c); 25 | int difSab = sa ^ sb; 26 | int sameSab = flip(difSab); 27 | int returnA = difSab * sa + sameSab * sc; 28 | int returnB = flip(returnA); 29 | return a * returnA + b * returnB; 30 | } 31 | 32 | public static void main(String[] args) { 33 | int a = -16; 34 | int b = -19; 35 | System.out.println(getMax1(a, b)); 36 | System.out.println(getMax2(a, b)); 37 | a = 2147483647; 38 | b = -2147480000; 39 | System.out.println(getMax1(a, b)); // wrong answer because of overflow 40 | System.out.println(getMax2(a, b)); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/class07/Code02_BalancedBinaryTree.java: -------------------------------------------------------------------------------- 1 | package class07; 2 | 3 | // 测试链接:https://leetcode.com/problems/balanced-binary-tree 4 | public class Code02_BalancedBinaryTree { 5 | 6 | public static class TreeNode { 7 | public int val; 8 | public TreeNode left; 9 | public TreeNode right; 10 | 11 | TreeNode(int val) { 12 | this.val = val; 13 | } 14 | } 15 | 16 | public static class Info { 17 | public boolean isBalanced; 18 | public int height; 19 | 20 | public Info(boolean i, int h) { 21 | isBalanced = i; 22 | height = h; 23 | } 24 | } 25 | 26 | public static boolean isBalanced(TreeNode root) { 27 | return process(root).isBalanced; 28 | } 29 | 30 | public static Info process(TreeNode root) { 31 | if (root == null) { 32 | return new Info(true, 0); 33 | } 34 | Info leftInfo = process(root.left); 35 | Info rightInfo = process(root.right); 36 | int height = Math.max(leftInfo.height, rightInfo.height) + 1; 37 | boolean isBalanced = leftInfo.isBalanced && rightInfo.isBalanced 38 | && Math.abs(leftInfo.height - rightInfo.height) < 2; 39 | return new Info(isBalanced, height); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/class07/Code01_BinaryTreeLevelOrderTraversalII.java: -------------------------------------------------------------------------------- 1 | package class07; 2 | 3 | import java.util.LinkedList; 4 | import java.util.List; 5 | import java.util.Queue; 6 | 7 | // 测试链接:https://leetcode.com/problems/binary-tree-level-order-traversal-ii 8 | public class Code01_BinaryTreeLevelOrderTraversalII { 9 | 10 | public static class TreeNode { 11 | public int val; 12 | public TreeNode left; 13 | public TreeNode right; 14 | 15 | TreeNode(int val) { 16 | this.val = val; 17 | } 18 | } 19 | 20 | public List> levelOrderBottom(TreeNode root) { 21 | List> ans = new LinkedList<>(); 22 | if (root == null) { 23 | return ans; 24 | } 25 | Queue queue = new LinkedList<>(); 26 | queue.add(root); 27 | while (!queue.isEmpty()) { 28 | int size = queue.size(); 29 | List curAns = new LinkedList<>(); 30 | for (int i = 0; i < size; i++) { 31 | TreeNode curNode = queue.poll(); 32 | curAns.add(curNode.val); 33 | if (curNode.left != null) { 34 | queue.add(curNode.left); 35 | } 36 | if (curNode.right != null) { 37 | queue.add(curNode.right); 38 | } 39 | } 40 | ans.add(0, curAns); 41 | } 42 | return ans; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/class06/Code01_MergeKSortedLists.java: -------------------------------------------------------------------------------- 1 | package class06; 2 | 3 | import java.util.Comparator; 4 | import java.util.PriorityQueue; 5 | 6 | // 测试链接:https://leetcode.com/problems/merge-k-sorted-lists/ 7 | public class Code01_MergeKSortedLists { 8 | 9 | public static class ListNode { 10 | public int val; 11 | public ListNode next; 12 | } 13 | 14 | public static class ListNodeComparator implements Comparator { 15 | 16 | @Override 17 | public int compare(ListNode o1, ListNode o2) { 18 | return o1.val - o2.val; 19 | } 20 | 21 | } 22 | 23 | public static ListNode mergeKLists(ListNode[] lists) { 24 | if (lists == null) { 25 | return null; 26 | } 27 | PriorityQueue heap = new PriorityQueue<>(new ListNodeComparator()); 28 | for (int i = 0; i < lists.length; i++) { 29 | if (lists[i] != null) { 30 | heap.add(lists[i]); 31 | } 32 | } 33 | if (heap.isEmpty()) { 34 | return null; 35 | } 36 | ListNode head = heap.poll(); 37 | ListNode pre = head; 38 | if (pre.next != null) { 39 | heap.add(pre.next); 40 | } 41 | while (!heap.isEmpty()) { 42 | ListNode cur = heap.poll(); 43 | pre.next = cur; 44 | pre = cur; 45 | if (cur.next != null) { 46 | heap.add(cur.next); 47 | } 48 | } 49 | return head; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/class01/Code01_PrintBinary.java: -------------------------------------------------------------------------------- 1 | package class01; 2 | 3 | public class Code01_PrintBinary { 4 | 5 | public static void print(int num) { 6 | for (int i = 31; i >= 0; i--) { 7 | System.out.print((num & (1 << i)) == 0 ? "0" : "1"); 8 | } 9 | System.out.println(); 10 | } 11 | 12 | public static void main(String[] args) { 13 | // 32位 14 | // int num = 4; 15 | // 16 | // print(num); 17 | // 18 | // 19 | // int test = 1123123; 20 | // print(test); 21 | // print(test<<1); 22 | // print(test<<2); 23 | // print(test<<8); 24 | // 25 | // 26 | // int a = Integer.MAX_VALUE; 27 | // System.out.println(a); 28 | 29 | // print(-1); 30 | // int a = Integer.MIN_VALUE; 31 | // print(a); 32 | 33 | // int b = 123823138; 34 | // int c = ~b; 35 | // print(b); 36 | // print(c); 37 | 38 | // print(-5); 39 | 40 | // System.out.println(Integer.MIN_VALUE); 41 | // System.out.println(Integer.MAX_VALUE); 42 | 43 | // int a = 12319283; 44 | // int b = 3819283; 45 | // print(a); 46 | // print(b); 47 | // System.out.println("============="); 48 | // print(a | b); 49 | // print(a & b); 50 | // print(a ^ b); 51 | 52 | // int a = Integer.MIN_VALUE; 53 | // print(a); 54 | // print(a >> 1); 55 | // print(a >>> 1); 56 | // 57 | // int c = Integer.MIN_VALUE; 58 | // int d = -c ; 59 | // 60 | // print(c); 61 | // print(d); 62 | 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/class04/Code04_ReverseNodesInKGroup.java: -------------------------------------------------------------------------------- 1 | 2 | 3 | package class04; 4 | 5 | // 测试链接:https://leetcode.com/problems/reverse-nodes-in-k-group/ 6 | public class Code04_ReverseNodesInKGroup { 7 | 8 | // 不要提交这个类 9 | public static class ListNode { 10 | public int val; 11 | public ListNode next; 12 | } 13 | 14 | public static ListNode reverseKGroup(ListNode head, int k) { 15 | ListNode start = head; 16 | ListNode end = getKGroupEnd(start, k); 17 | if (end == null) { 18 | return head; 19 | } 20 | // 第一组凑齐了! 21 | head = end; 22 | reverse(start, end); 23 | // 上一组的结尾节点 24 | ListNode lastEnd = start; 25 | while (lastEnd.next != null) { 26 | start = lastEnd.next; 27 | end = getKGroupEnd(start, k); 28 | if (end == null) { 29 | return head; 30 | } 31 | reverse(start, end); 32 | lastEnd.next = end; 33 | lastEnd = start; 34 | } 35 | return head; 36 | } 37 | 38 | public static ListNode getKGroupEnd(ListNode start, int k) { 39 | while (--k != 0 && start != null) { 40 | start = start.next; 41 | } 42 | return start; 43 | } 44 | 45 | public static void reverse(ListNode start, ListNode end) { 46 | end = end.next; 47 | ListNode pre = null; 48 | ListNode cur = start; 49 | ListNode next = null; 50 | while (cur != end) { 51 | next = cur.next; 52 | cur.next = pre; 53 | pre = cur; 54 | cur = next; 55 | } 56 | start.next = end; 57 | } 58 | 59 | } -------------------------------------------------------------------------------- /src/class05/Code02_BitMap2.java: -------------------------------------------------------------------------------- 1 | package class05; 2 | 3 | import java.util.HashSet; 4 | 5 | public class Code02_BitMap2 { 6 | 7 | // 这个类的实现是正确的 8 | public static class BitMap { 9 | 10 | private long[] bits; 11 | 12 | public BitMap(int max) { 13 | bits = new long[(max + 64) >> 6]; 14 | } 15 | 16 | public void add(int num) { 17 | bits[num >> 6] |= (1L << (num & 63)); 18 | } 19 | 20 | public void delete(int num) { 21 | bits[num >> 6] &= ~(1L << (num & 63)); 22 | } 23 | 24 | public boolean contains(int num) { 25 | return (bits[num >> 6] & (1L << (num & 63))) != 0; 26 | } 27 | 28 | } 29 | 30 | public static void main(String[] args) { 31 | System.out.println("测试开始!"); 32 | int max = 10000; 33 | BitMap bitMap = new BitMap(max); 34 | HashSet set = new HashSet<>(); 35 | int testTime = 10000000; 36 | for (int i = 0; i < testTime; i++) { 37 | int num = (int) (Math.random() * (max + 1)); 38 | double decide = Math.random(); 39 | if (decide < 0.333) { 40 | bitMap.add(num); 41 | set.add(num); 42 | } else if (decide < 0.666) { 43 | bitMap.delete(num); 44 | set.remove(num); 45 | } else { 46 | if (bitMap.contains(num) != set.contains(num)) { 47 | System.out.println("Oops!"); 48 | break; 49 | } 50 | } 51 | } 52 | for (int num = 0; num <= max; num++) { 53 | if (bitMap.contains(num) != set.contains(num)) { 54 | System.out.println("Oops!"); 55 | } 56 | } 57 | System.out.println("测试结束!"); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/class05/Code01_BitMap1.java: -------------------------------------------------------------------------------- 1 | package class05; 2 | 3 | import java.util.HashSet; 4 | 5 | // 这个类的实现是错误的 6 | // 请问为什么? 7 | public class Code01_BitMap1 { 8 | 9 | public static class BitMap { 10 | 11 | private long[] bits; 12 | 13 | public BitMap(int max) { 14 | bits = new long[(max + 64) >> 6]; 15 | } 16 | 17 | public void add(int num) { 18 | bits[num >> 6] |= (1 << (num & 63)); 19 | } 20 | 21 | public void delete(int num) { 22 | bits[num >> 6] &= ~(1 << (num & 63)); 23 | } 24 | 25 | public boolean contains(int num) { 26 | return (bits[num >> 6] & (1 << (num & 63))) != 0; 27 | } 28 | 29 | } 30 | 31 | public static void main(String[] args) { 32 | System.out.println("测试开始!"); 33 | int max = 10000; 34 | BitMap bitMap = new BitMap(max); 35 | HashSet set = new HashSet<>(); 36 | int testTime = 10000000; 37 | for (int i = 0; i < testTime; i++) { 38 | int num = (int) (Math.random() * (max + 1)); 39 | double decide = Math.random(); 40 | if (decide < 0.333) { 41 | bitMap.add(num); 42 | set.add(num); 43 | } else if (decide < 0.666) { 44 | bitMap.delete(num); 45 | set.remove(num); 46 | } else { 47 | if (bitMap.contains(num) != set.contains(num)) { 48 | System.out.println("Oops!"); 49 | break; 50 | } 51 | } 52 | } 53 | for (int num = 0; num <= max; num++) { 54 | if (bitMap.contains(num) != set.contains(num)) { 55 | System.out.println("Oops!"); 56 | } 57 | } 58 | System.out.println("测试结束!"); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/class07/Code04_PathSumII.java: -------------------------------------------------------------------------------- 1 | package class07; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Code04_PathSumII { 7 | 8 | // 测试链接:https://leetcode.com/problems/path-sum-ii 9 | public static class TreeNode { 10 | public int val; 11 | public TreeNode left; 12 | public TreeNode right; 13 | 14 | TreeNode(int val) { 15 | this.val = val; 16 | } 17 | } 18 | 19 | public static List> pathSum(TreeNode root, int sum) { 20 | List> ans = new ArrayList<>(); 21 | if (root == null) { 22 | return ans; 23 | } 24 | ArrayList path = new ArrayList<>(); 25 | process(root, path, 0, sum, ans); 26 | return ans; 27 | } 28 | 29 | public static void process(TreeNode x, List path, int preSum, int sum, List> ans) { 30 | if (x.left == null && x.right == null) { 31 | if (preSum + x.val == sum) { 32 | path.add(x.val); 33 | ans.add(copy(path)); 34 | path.remove(path.size() - 1); 35 | } 36 | return; 37 | } 38 | // x 非叶节点 39 | path.add(x.val); 40 | preSum += x.val; 41 | if (x.left != null) { 42 | process(x.left, path, preSum, sum, ans); 43 | } 44 | if (x.right != null) { 45 | process(x.right, path, preSum, sum, ans); 46 | } 47 | path.remove(path.size() - 1); 48 | } 49 | 50 | public static List copy(List path) { 51 | List ans = new ArrayList<>(); 52 | for (Integer num : path) { 53 | ans.add(num); 54 | } 55 | return ans; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/class04/Code05_AddTwoNumbers.java: -------------------------------------------------------------------------------- 1 | package class04; 2 | 3 | // 测试链接:https://leetcode.com/problems/add-two-numbers/ 4 | public class Code05_AddTwoNumbers { 5 | 6 | // 不要提交这个类 7 | public static class ListNode { 8 | public int val; 9 | public ListNode next; 10 | 11 | public ListNode(int val) { 12 | this.val = val; 13 | } 14 | 15 | public ListNode(int val, ListNode next) { 16 | this.val = val; 17 | this.next = next; 18 | } 19 | } 20 | 21 | public static ListNode addTwoNumbers(ListNode head1, ListNode head2) { 22 | int len1 = listLength(head1); 23 | int len2 = listLength(head2); 24 | ListNode l = len1 >= len2 ? head1 : head2; 25 | ListNode s = l == head1 ? head2 : head1; 26 | ListNode curL = l; 27 | ListNode curS = s; 28 | ListNode last = curL; 29 | int carry = 0; 30 | int curNum = 0; 31 | while (curS != null) { 32 | curNum = curL.val + curS.val + carry; 33 | curL.val = (curNum % 10); 34 | carry = curNum / 10; 35 | last = curL; 36 | curL = curL.next; 37 | curS = curS.next; 38 | } 39 | while (curL != null) { 40 | curNum = curL.val + carry; 41 | curL.val = (curNum % 10); 42 | carry = curNum / 10; 43 | last = curL; 44 | curL = curL.next; 45 | } 46 | if (carry != 0) { 47 | last.next = new ListNode(1); 48 | } 49 | return l; 50 | } 51 | 52 | // 求链表长度 53 | public static int listLength(ListNode head) { 54 | int len = 0; 55 | while (head != null) { 56 | len++; 57 | head = head.next; 58 | } 59 | return len; 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/class06/TraversalBinaryTree.java: -------------------------------------------------------------------------------- 1 | package class06; 2 | 3 | public class TraversalBinaryTree { 4 | 5 | public static class Node { 6 | public int value; 7 | public Node left; 8 | public Node right; 9 | 10 | public Node(int v) { 11 | value = v; 12 | } 13 | } 14 | 15 | public static void f(Node head) { 16 | if (head == null) { 17 | return; 18 | } 19 | // 1 20 | f(head.left); 21 | // 2 22 | f(head.right); 23 | // 3 24 | } 25 | 26 | // 先序打印所有节点 27 | public static void pre(Node head) { 28 | if (head == null) { 29 | return; 30 | } 31 | System.out.println(head.value); 32 | pre(head.left); 33 | pre(head.right); 34 | } 35 | 36 | public static void in(Node head) { 37 | if (head == null) { 38 | return; 39 | } 40 | in(head.left); 41 | System.out.println(head.value); 42 | in(head.right); 43 | } 44 | 45 | public static void pos(Node head) { 46 | if (head == null) { 47 | return; 48 | } 49 | pos(head.left); 50 | pos(head.right); 51 | System.out.println(head.value); 52 | } 53 | 54 | public static void main(String[] args) { 55 | Node head = new Node(1); 56 | head.left = new Node(2); 57 | head.right = new Node(3); 58 | head.left.left = new Node(4); 59 | head.left.right = new Node(5); 60 | head.right.left = new Node(6); 61 | head.right.right = new Node(7); 62 | 63 | pre(head); 64 | System.out.println("========"); 65 | in(head); 66 | System.out.println("========"); 67 | pos(head); 68 | System.out.println("========"); 69 | 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/class07/Code03_PathSum.java: -------------------------------------------------------------------------------- 1 | package class07; 2 | 3 | public class Code03_PathSum { 4 | 5 | // 测试链接:https://leetcode.com/problems/path-sum 6 | public static class TreeNode { 7 | public int val; 8 | public TreeNode left; 9 | public TreeNode right; 10 | 11 | TreeNode(int val) { 12 | this.val = val; 13 | } 14 | } 15 | 16 | public static boolean isSum = false; 17 | 18 | public static boolean hasPathSum(TreeNode root, int sum) { 19 | if (root == null) { 20 | return false; 21 | } 22 | isSum = false; 23 | process(root, 0, sum); 24 | return isSum; 25 | } 26 | 27 | public static void process(TreeNode x, int preSum, int sum) { 28 | if (x.left == null && x.right == null) { 29 | if (x.val + preSum == sum) { 30 | isSum = true; 31 | } 32 | return; 33 | } 34 | // x是非叶节点 35 | preSum += x.val; 36 | if (x.left != null) { 37 | process(x.left, preSum, sum); 38 | } 39 | if (x.right != null) { 40 | process(x.right, preSum, sum); 41 | } 42 | } 43 | 44 | // public static boolean hasPathSum(TreeNode root, int sum) { 45 | // if (root == null) { 46 | // return false; 47 | // } 48 | // return process(root, sum); 49 | // } 50 | // 51 | // public static boolean process(TreeNode root, int rest) { 52 | // if (root.left == null && root.right == null) { 53 | // return root.val == rest; 54 | // } 55 | // boolean ans = root.left != null ? process(root.left, rest - root.val) : false; 56 | // ans |= root.right != null ? process(root.right, rest - root.val) : false; 57 | // return ans; 58 | // } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/class02/Code03_EqualProbabilityRandom.java: -------------------------------------------------------------------------------- 1 | package class02; 2 | 3 | public class Code03_EqualProbabilityRandom { 4 | 5 | // 内部内容不可见 6 | public static int f() { 7 | return Math.random() < 0.8 ? 0 : 1; 8 | } 9 | 10 | // 等概率返回0和1 11 | public static int g() { 12 | int first = 0; 13 | do { 14 | first = f(); // 0 1 15 | } while (first == f()); 16 | return first; 17 | } 18 | 19 | // 这个结构是唯一的随机机制 20 | // 你只能初始化并使用,不可修改 21 | public static class RandomBox { 22 | private final double p; 23 | 24 | // 初始化时请一定满足:0 < zeroP < 1 25 | public RandomBox(double zeroP) { 26 | p = zeroP; 27 | } 28 | 29 | public int random() { 30 | return Math.random() < p ? 0 : 1; 31 | } 32 | 33 | } 34 | 35 | // 底层依赖一个以p概率返回0,以1-p概率返回1的随机函数rand01p 36 | // 如何加工出等概率返回0和1的函数 37 | public static int rand01(RandomBox randomBox) { 38 | int num; 39 | do { 40 | num = randomBox.random(); 41 | } while (num == randomBox.random()); 42 | return num; 43 | } 44 | 45 | public static void main(String[] args) { 46 | int[] count = new int[2];// 0 1 47 | for (int i = 0; i < 1000000; i++) { 48 | int ans = g(); 49 | count[ans]++; 50 | } 51 | System.out.println(count[0] + " , " + count[1]); 52 | 53 | // double zeroP = 0.88; 54 | // RandomBox randomBox = new RandomBox(zeroP); 55 | // 56 | // int testTime = 10000000; 57 | // int count = 0; 58 | // for (int i = 0; i < testTime; i++) { 59 | // if (rand01(randomBox) == 0) { 60 | // count++; 61 | // } 62 | // } 63 | // System.out.println((double) count / (double) testTime); 64 | 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/class05/Code03_BitAddMinusMultiDiv.java: -------------------------------------------------------------------------------- 1 | package class05; 2 | 3 | // 测试链接:https://leetcode.com/problems/divide-two-integers 4 | public class Code03_BitAddMinusMultiDiv { 5 | 6 | public static int add(int a, int b) { 7 | int sum = a; 8 | while (b != 0) { 9 | sum = a ^ b; 10 | b = (a & b) << 1; 11 | a = sum; 12 | } 13 | return sum; 14 | } 15 | 16 | public static int negNum(int n) { 17 | return add(~n, 1); 18 | } 19 | 20 | public static int minus(int a, int b) { 21 | return add(a, negNum(b)); 22 | } 23 | 24 | public static int multi(int a, int b) { 25 | int res = 0; 26 | while (b != 0) { 27 | if ((b & 1) != 0) { 28 | res = add(res, a); 29 | } 30 | a <<= 1; 31 | b >>>= 1; 32 | } 33 | return res; 34 | } 35 | 36 | public static boolean isNeg(int n) { 37 | return n < 0; 38 | } 39 | 40 | public static int div(int a, int b) { 41 | int x = isNeg(a) ? negNum(a) : a; 42 | int y = isNeg(b) ? negNum(b) : b; 43 | int res = 0; 44 | for (int i = 30; i >= 0; i = minus(i, 1)) { 45 | if ((x >> i) >= y) { 46 | res |= (1 << i); 47 | x = minus(x, y << i); 48 | } 49 | } 50 | return isNeg(a) ^ isNeg(b) ? negNum(res) : res; 51 | } 52 | 53 | public static int divide(int a, int b) { 54 | if (a == Integer.MIN_VALUE && b == Integer.MIN_VALUE) { 55 | return 1; 56 | } else if (b == Integer.MIN_VALUE) { 57 | return 0; 58 | } else if (a == Integer.MIN_VALUE) { 59 | if (b == negNum(1)) { 60 | return Integer.MAX_VALUE; 61 | } else { 62 | int c = div(add(a, 1), b); 63 | return add(c, div(minus(a, multi(c, b)), b)); 64 | } 65 | } else { 66 | return div(a, b); 67 | } 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/class03/Code01_BSExist.java: -------------------------------------------------------------------------------- 1 | package class03; 2 | 3 | import java.util.Arrays; 4 | 5 | public class Code01_BSExist { 6 | 7 | // arr保证有序 8 | public static boolean find(int[] arr, int num) { 9 | if (arr == null || arr.length == 0) { 10 | return false; 11 | } 12 | int L = 0; 13 | int R = arr.length - 1; 14 | while (L <= R) { 15 | int mid = (L + R) / 2; 16 | if (arr[mid] == num) { 17 | return true; 18 | } else if (arr[mid] < num) { 19 | L = mid + 1; 20 | } else { 21 | R = mid - 1; 22 | } 23 | } 24 | return false; 25 | } 26 | 27 | // for test 28 | public static boolean test(int[] sortedArr, int num) { 29 | for (int cur : sortedArr) { 30 | if (cur == num) { 31 | return true; 32 | } 33 | } 34 | return false; 35 | } 36 | 37 | // for test 38 | public static int[] generateRandomArray(int maxSize, int maxValue) { 39 | int[] arr = new int[(int) ((maxSize + 1) * Math.random())]; 40 | for (int i = 0; i < arr.length; i++) { 41 | arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random()); 42 | } 43 | return arr; 44 | } 45 | 46 | public static void main(String[] args) { 47 | int testTime = 500000; 48 | int maxSize = 10; 49 | int maxValue = 100; 50 | boolean succeed = true; 51 | for (int i = 0; i < testTime; i++) { 52 | int[] arr = generateRandomArray(maxSize, maxValue); 53 | Arrays.sort(arr); 54 | int value = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random()); 55 | if (test(arr, value) != find(arr, value)) { 56 | System.out.println("出错了!"); 57 | succeed = false; 58 | break; 59 | } 60 | } 61 | System.out.println(succeed ? "Nice!" : "Fucking fucked!"); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/class06/ShowComparator2.java: -------------------------------------------------------------------------------- 1 | package class06; 2 | 3 | import java.util.Comparator; 4 | import java.util.PriorityQueue; 5 | 6 | public class ShowComparator2 { 7 | 8 | public static class MyComparator implements Comparator { 9 | 10 | // 负,第一个参数在前 11 | // 正,第二个参数在前 12 | // 0, 谁放前都行 13 | @Override 14 | public int compare(Integer o1, Integer o2) { 15 | if (o1 < o2) { 16 | return 1; 17 | } else if (o1 > o2) { 18 | return -1; 19 | } else { 20 | return 0; 21 | } 22 | } 23 | 24 | } 25 | 26 | public static class Student { 27 | public String name; 28 | public int id; 29 | public int age; 30 | 31 | public Student(String name, int id, int age) { 32 | this.name = name; 33 | this.id = id; 34 | this.age = age; 35 | } 36 | } 37 | 38 | // 谁id大,谁放前! 39 | public static class IdComparator implements Comparator { 40 | 41 | // 如果返回负数,认为第一个参数应该排在前面 42 | // 如果返回正数,认为第二个参数应该排在前面 43 | // 如果返回0,认为谁放前面无所谓 44 | @Override 45 | public int compare(Student o1, Student o2) { 46 | if (o1.id < o2.id) { 47 | return 1; 48 | } else if (o2.id < o1.id) { 49 | return -1; 50 | } else { 51 | return 0; 52 | } 53 | } 54 | } 55 | 56 | public static void main(String[] args) { 57 | String str1 = "abc"; 58 | String str2 = "b"; 59 | System.out.println(str1.compareTo(str2)); 60 | PriorityQueue heap = new PriorityQueue<>(new IdComparator()); 61 | Student s1 = new Student("张三", 5, 27); 62 | Student s2 = new Student("李四", 1, 17); 63 | Student s3 = new Student("王五", 4, 29); 64 | Student s4 = new Student("赵六", 3, 9); 65 | Student s5 = new Student("左七", 2, 34); 66 | heap.add(s1); 67 | heap.add(s2); 68 | heap.add(s3); 69 | heap.add(s4); 70 | heap.add(s5); 71 | System.out.println("========="); 72 | while (!heap.isEmpty()) { 73 | Student s = heap.poll(); 74 | System.out.println(s.name + ", " + s.id + ", " + s.age); 75 | } 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /src/class03/Code03_BSNearRight.java: -------------------------------------------------------------------------------- 1 | package class03; 2 | 3 | import java.util.Arrays; 4 | 5 | public class Code03_BSNearRight { 6 | 7 | // 在arr上,找满足<=value的最右位置 8 | public static int nearestIndex(int[] arr, int value) { 9 | int L = 0; 10 | int R = arr.length - 1; 11 | int index = -1; // 记录最右的对号 12 | while (L <= R) { 13 | int mid = L + ((R - L) >> 1); 14 | if (arr[mid] <= value) { 15 | index = mid; 16 | L = mid + 1; 17 | } else { 18 | R = mid - 1; 19 | } 20 | } 21 | return index; 22 | } 23 | 24 | // for test 25 | public static int test(int[] arr, int value) { 26 | for (int i = arr.length - 1; i >= 0; i--) { 27 | if (arr[i] <= value) { 28 | return i; 29 | } 30 | } 31 | return -1; 32 | } 33 | 34 | // for test 35 | public static int[] generateRandomArray(int maxSize, int maxValue) { 36 | int[] arr = new int[(int) ((maxSize + 1) * Math.random())]; 37 | for (int i = 0; i < arr.length; i++) { 38 | arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random()); 39 | } 40 | return arr; 41 | } 42 | 43 | // for test 44 | public static void printArray(int[] arr) { 45 | if (arr == null) { 46 | return; 47 | } 48 | for (int i = 0; i < arr.length; i++) { 49 | System.out.print(arr[i] + " "); 50 | } 51 | System.out.println(); 52 | } 53 | 54 | public static void main(String[] args) { 55 | int testTime = 500000; 56 | int maxSize = 10; 57 | int maxValue = 100; 58 | boolean succeed = true; 59 | for (int i = 0; i < testTime; i++) { 60 | int[] arr = generateRandomArray(maxSize, maxValue); 61 | Arrays.sort(arr); 62 | int value = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random()); 63 | if (test(arr, value) != nearestIndex(arr, value)) { 64 | printArray(arr); 65 | System.out.println(value); 66 | System.out.println(test(arr, value)); 67 | System.out.println(nearestIndex(arr, value)); 68 | succeed = false; 69 | break; 70 | } 71 | } 72 | System.out.println(succeed ? "Nice!" : "Fucking fucked!"); 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/class01/Code03_Sort.java: -------------------------------------------------------------------------------- 1 | package class01; 2 | 3 | public class Code03_Sort { 4 | 5 | public static void swap(int[] arr, int i, int j) { 6 | int tmp = arr[j]; 7 | arr[j] = arr[i]; 8 | arr[i] = tmp; 9 | } 10 | 11 | public static void selectSort(int[] arr) { 12 | if (arr == null || arr.length < 2) { 13 | return; 14 | } 15 | int N = arr.length; 16 | for (int i = 0; i < N; i++) { 17 | int minValueIndex = i; 18 | for (int j = i + 1; j < N; j++) { 19 | minValueIndex = arr[j] < arr[minValueIndex] ? j : minValueIndex; 20 | } 21 | swap(arr, i, minValueIndex); 22 | } 23 | } 24 | 25 | public static void bubbleSort(int[] arr) { 26 | if (arr == null || arr.length < 2) { 27 | return; 28 | } 29 | int N = arr.length; 30 | for (int end = N - 1; end >= 0; end--) { 31 | for (int second = 1; second <= end; second++) { 32 | if (arr[second - 1] > arr[second]) { 33 | swap(arr, second - 1, second); 34 | } 35 | } 36 | } 37 | } 38 | 39 | public static void insertSort1(int[] arr) { 40 | if (arr == null || arr.length < 2) { 41 | return; 42 | } 43 | int N = arr.length; 44 | for (int end = 1; end < N; end++) { 45 | int newNumIndex = end; 46 | while (newNumIndex - 1 >= 0 && arr[newNumIndex - 1] > arr[newNumIndex]) { 47 | swap(arr, newNumIndex - 1, newNumIndex); 48 | newNumIndex--; 49 | } 50 | } 51 | } 52 | 53 | public static void insertSort2(int[] arr) { 54 | if (arr == null || arr.length < 2) { 55 | return; 56 | } 57 | int N = arr.length; 58 | for (int end = 1; end < N; end++) { 59 | for (int pre = end - 1; pre >= 0 && arr[pre] > arr[pre + 1]; pre--) { 60 | swap(arr, pre, pre + 1); 61 | } 62 | } 63 | } 64 | 65 | public static void printArray(int[] arr) { 66 | for (int i = 0; i < arr.length; i++) { 67 | System.out.print(arr[i] + " "); 68 | } 69 | System.out.println(); 70 | } 71 | 72 | public static void main(String[] args) { 73 | int[] arr = { 7, 1, 3, 5, 1, 6, 8, 1, 3, 5, 7, 5, 6 }; 74 | printArray(arr); 75 | insertSort2(arr); 76 | printArray(arr); 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /src/class03/Code02_BSNearLeft.java: -------------------------------------------------------------------------------- 1 | package class03; 2 | 3 | import java.util.Arrays; 4 | 5 | public class Code02_BSNearLeft { 6 | 7 | // arr有序的,>=num 最左 8 | public static int mostLeftNoLessNumIndex(int[] arr, int num) { 9 | if (arr == null || arr.length == 0) { 10 | return -1; 11 | } 12 | int L = 0; 13 | int R = arr.length - 1; 14 | int ans = -1; 15 | while (L <= R) { 16 | int mid = (L + R) / 2; 17 | if (arr[mid] >= num) { 18 | ans = mid; 19 | R = mid - 1; 20 | } else { 21 | L = mid + 1; 22 | } 23 | } 24 | return ans; 25 | } 26 | 27 | // for test 28 | public static int test(int[] arr, int value) { 29 | for (int i = 0; i < arr.length; i++) { 30 | if (arr[i] >= value) { 31 | return i; 32 | } 33 | } 34 | return -1; 35 | } 36 | 37 | // for test 38 | public static int[] generateRandomArray(int maxSize, int maxValue) { 39 | int[] arr = new int[(int) ((maxSize + 1) * Math.random())]; 40 | for (int i = 0; i < arr.length; i++) { 41 | arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random()); 42 | } 43 | return arr; 44 | } 45 | 46 | // for test 47 | public static void printArray(int[] arr) { 48 | if (arr == null) { 49 | return; 50 | } 51 | for (int i = 0; i < arr.length; i++) { 52 | System.out.print(arr[i] + " "); 53 | } 54 | System.out.println(); 55 | } 56 | 57 | public static void main(String[] args) { 58 | int testTime = 500000; 59 | int maxSize = 10; 60 | int maxValue = 100; 61 | boolean succeed = true; 62 | for (int i = 0; i < testTime; i++) { 63 | int[] arr = generateRandomArray(maxSize, maxValue); 64 | Arrays.sort(arr); 65 | int value = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random()); 66 | if (test(arr, value) != mostLeftNoLessNumIndex(arr, value)) { 67 | printArray(arr); 68 | System.out.println(value); 69 | System.out.println(test(arr, value)); 70 | System.out.println(mostLeftNoLessNumIndex(arr, value)); 71 | succeed = false; 72 | break; 73 | } 74 | } 75 | System.out.println(succeed ? "Nice!" : "Fucking fucked!"); 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /src/class06/Code05_ConstructBinaryTreeFromPreorderAndInorderTraversal.java: -------------------------------------------------------------------------------- 1 | package class06; 2 | 3 | import java.util.HashMap; 4 | 5 | //测试链接:https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal 6 | public class Code05_ConstructBinaryTreeFromPreorderAndInorderTraversal { 7 | 8 | public static class TreeNode { 9 | int val; 10 | TreeNode left; 11 | TreeNode right; 12 | 13 | TreeNode(int val) { 14 | this.val = val; 15 | } 16 | } 17 | 18 | public static TreeNode buildTree1(int[] pre, int[] in) { 19 | if (pre == null || in == null || pre.length != in.length) { 20 | return null; 21 | } 22 | return f(pre, 0, pre.length - 1, in, 0, in.length - 1); 23 | } 24 | 25 | // 有一棵树,先序结果是pre[L1...R1],中序结果是in[L2...R2] 26 | // 请建出整棵树返回头节点 27 | public static TreeNode f(int[] pre, int L1, int R1, int[] in, int L2, int R2) { 28 | if (L1 > R1) { 29 | return null; 30 | } 31 | TreeNode head = new TreeNode(pre[L1]); 32 | if (L1 == R1) { 33 | return head; 34 | } 35 | int find = L2; 36 | while (in[find] != pre[L1]) { 37 | find++; 38 | } 39 | head.left = f(pre, L1 + 1, L1 + find - L2, in, L2, find - 1); 40 | head.right = f(pre, L1 + find - L2 + 1, R1, in, find + 1, R2); 41 | return head; 42 | } 43 | 44 | public static TreeNode buildTree2(int[] pre, int[] in) { 45 | if (pre == null || in == null || pre.length != in.length) { 46 | return null; 47 | } 48 | HashMap valueIndexMap = new HashMap<>(); 49 | for (int i = 0; i < in.length; i++) { 50 | valueIndexMap.put(in[i], i); 51 | } 52 | return g(pre, 0, pre.length - 1, in, 0, in.length - 1, valueIndexMap); 53 | } 54 | 55 | // 有一棵树,先序结果是pre[L1...R1],中序结果是in[L2...R2] 56 | // 请建出整棵树返回头节点 57 | public static TreeNode g(int[] pre, int L1, int R1, int[] in, int L2, int R2, 58 | HashMap valueIndexMap) { 59 | if (L1 > R1) { 60 | return null; 61 | } 62 | TreeNode head = new TreeNode(pre[L1]); 63 | if (L1 == R1) { 64 | return head; 65 | } 66 | int find = valueIndexMap.get(pre[L1]); 67 | head.left = g(pre, L1 + 1, L1 + find - L2, in, L2, find - 1, valueIndexMap); 68 | head.right = g(pre, L1 + find - L2 + 1, R1, in, find + 1, R2, valueIndexMap); 69 | return head; 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/class03/Code04_BSAwesome.java: -------------------------------------------------------------------------------- 1 | package class03; 2 | 3 | public class Code04_BSAwesome { 4 | 5 | // arr 相邻的数不相等! 6 | public static int oneMinIndex(int[] arr) { 7 | if (arr == null || arr.length == 0) { 8 | return -1; 9 | } 10 | int N = arr.length; 11 | if (N == 1) { 12 | return 0; 13 | } 14 | if (arr[0] < arr[1]) { 15 | return 0; 16 | } 17 | if (arr[N - 1] < arr[N - 2]) { 18 | return N - 1; 19 | } 20 | int L = 0; 21 | int R = N - 1; 22 | // L...R 肯定有局部最小 23 | while (L < R - 1) { 24 | int mid = (L + R) / 2; 25 | if (arr[mid] < arr[mid - 1] && arr[mid] < arr[mid + 1]) { 26 | return mid; 27 | } else { 28 | if (arr[mid] > arr[mid - 1]) { 29 | R = mid - 1; 30 | } else { 31 | L = mid + 1; 32 | } 33 | } 34 | } 35 | return arr[L] < arr[R] ? L : R; 36 | } 37 | 38 | // 生成随机数组,且相邻数不相等 39 | public static int[] randomArray(int maxLen, int maxValue) { 40 | int len = (int) (Math.random() * maxLen); 41 | int[] arr = new int[len]; 42 | if (len > 0) { 43 | arr[0] = (int) (Math.random() * maxValue); 44 | for (int i = 1; i < len; i++) { 45 | do { 46 | arr[i] = (int) (Math.random() * maxValue); 47 | } while (arr[i] == arr[i - 1]); 48 | } 49 | } 50 | return arr; 51 | } 52 | 53 | // 也用于测试 54 | public static boolean check(int[] arr, int minIndex) { 55 | if (arr.length == 0) { 56 | return minIndex == -1; 57 | } 58 | int left = minIndex - 1; 59 | int right = minIndex + 1; 60 | boolean leftBigger = left >= 0 ? arr[left] > arr[minIndex] : true; 61 | boolean rightBigger = right < arr.length ? arr[right] > arr[minIndex] : true; 62 | return leftBigger && rightBigger; 63 | } 64 | 65 | public static void printArray(int[] arr) { 66 | for (int num : arr) { 67 | System.out.print(num + " "); 68 | } 69 | System.out.println(); 70 | } 71 | 72 | public static void main(String[] args) { 73 | int maxLen = 100; 74 | int maxValue = 200; 75 | int testTime = 1000000; 76 | System.out.println("测试开始"); 77 | for (int i = 0; i < testTime; i++) { 78 | int[] arr = randomArray(maxLen, maxValue); 79 | int ans = oneMinIndex(arr); 80 | if (!check(arr, ans)) { 81 | printArray(arr); 82 | System.out.println(ans); 83 | break; 84 | } 85 | } 86 | System.out.println("测试结束"); 87 | 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /src/class02/Code03_Comp.java: -------------------------------------------------------------------------------- 1 | package class02; 2 | 3 | public class Code03_Comp { 4 | 5 | public static void selectionSort(int[] arr) { 6 | if (arr == null || arr.length < 2) { 7 | return; 8 | } 9 | for (int i = 0; i < arr.length - 1; i++) { 10 | int minIndex = i; 11 | for (int j = i + 1; j < arr.length; j++) { 12 | if (arr[j] < arr[minIndex]) { 13 | minIndex = j; 14 | } 15 | } 16 | swap(arr, i, minIndex); 17 | } 18 | } 19 | 20 | public static void swap(int[] arr, int i, int j) { 21 | int tmp = arr[i]; 22 | arr[i] = arr[j]; 23 | arr[j] = tmp; 24 | } 25 | 26 | public static void insertionSort(int[] arr) { 27 | if (arr == null || arr.length < 2) { 28 | return; 29 | } 30 | for (int i = 1; i < arr.length; i++) { // 0 ~ i 做到有序 31 | for (int j = i - 1; j >= 0 && arr[j] > arr[j + 1]; j--) { 32 | swap(arr, j, j + 1); 33 | } 34 | } 35 | } 36 | 37 | // 返回一个数组arr,arr长度[0,maxLen-1],arr中的每个值[0,maxValue-1] 38 | public static int[] lenRandomValueRandom(int maxLen, int maxValue) { 39 | int len = (int) (Math.random() * maxLen); 40 | int[] ans = new int[len]; 41 | for (int i = 0; i < len; i++) { 42 | ans[i] = (int) (Math.random() * maxValue); 43 | } 44 | return ans; 45 | } 46 | 47 | public static int[] copyArray(int[] arr) { 48 | int[] ans = new int[arr.length]; 49 | for (int i = 0; i < arr.length; i++) { 50 | ans[i] = arr[i]; 51 | } 52 | return ans; 53 | } 54 | 55 | // arr1和arr2一定等长 56 | public static boolean isSorted(int[] arr) { 57 | if (arr.length < 2) { 58 | return true; 59 | } 60 | int max = arr[0]; 61 | for (int i = 1; i < arr.length; i++) { 62 | if (max > arr[i]) { 63 | return false; 64 | } 65 | max = Math.max(max, arr[i]); 66 | } 67 | return true; 68 | } 69 | 70 | public static void main(String[] args) { 71 | int maxLen = 5; 72 | int maxValue = 1000; 73 | int testTime = 10000; 74 | for (int i = 0; i < testTime; i++) { 75 | int[] arr1 = lenRandomValueRandom(maxLen, maxValue); 76 | int[] tmp = copyArray(arr1); 77 | selectionSort(arr1); 78 | if (!isSorted(arr1)) { 79 | for (int j = 0; j < tmp.length; j++) { 80 | System.out.print(tmp[j] + " "); 81 | } 82 | System.out.println(); 83 | System.out.println("选择排序错了!"); 84 | break; 85 | } 86 | } 87 | 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /src/class07/Code05_IsBinarySearchTree.java: -------------------------------------------------------------------------------- 1 | package class07; 2 | 3 | public class Code05_IsBinarySearchTree { 4 | 5 | public static class TreeNode { 6 | public int val; 7 | public TreeNode left; 8 | public TreeNode right; 9 | 10 | TreeNode(int val) { 11 | this.val = val; 12 | } 13 | } 14 | 15 | public static class Info { 16 | public boolean isBST; 17 | public int max; 18 | public int min; 19 | 20 | public Info(boolean is, int ma, int mi) { 21 | isBST = is; 22 | max = ma; 23 | min = mi; 24 | } 25 | } 26 | 27 | // public static Info process(TreeNode x) { 28 | // if (x == null) { 29 | // return null; 30 | // } 31 | // Info leftInfo = process(x.left); 32 | // Info rightInfo = process(x.right); 33 | // int max = x.val; 34 | // int min = x.val; 35 | // if (leftInfo != null) { 36 | // max = Math.max(leftInfo.max, max); 37 | // min = Math.min(leftInfo.min, min); 38 | // } 39 | // if (rightInfo != null) { 40 | // max = Math.max(rightInfo.max, max); 41 | // min = Math.min(rightInfo.min, min); 42 | // } 43 | // boolean isBST = true; 44 | // if (leftInfo != null && !leftInfo.isBST) { 45 | // isBST = false; 46 | // } 47 | // if (rightInfo != null && !rightInfo.isBST) { 48 | // isBST = false; 49 | // } 50 | // boolean leftMaxLessX = leftInfo == null ? true : (leftInfo.max < x.val); 51 | // boolean rightMinMoreX = rightInfo == null ? true : (rightInfo.min > x.val); 52 | // if (!(leftMaxLessX && rightMinMoreX)) { 53 | // isBST = false; 54 | // } 55 | // return new Info(isBST, max, min); 56 | // } 57 | 58 | public static Info process(TreeNode x) { 59 | if (x == null) { 60 | return null; 61 | } 62 | Info leftInfo = process(x.left); 63 | Info rightInfo = process(x.right); 64 | int max = x.val; 65 | int min = x.val; 66 | if (leftInfo != null) { 67 | max = Math.max(leftInfo.max, max); 68 | min = Math.min(leftInfo.min, min); 69 | } 70 | if (rightInfo != null) { 71 | max = Math.max(rightInfo.max, max); 72 | min = Math.min(rightInfo.min, min); 73 | } 74 | boolean isBST = false; 75 | boolean leftIsBst = leftInfo == null ? true : leftInfo.isBST; 76 | boolean rightIsBst = rightInfo == null ? true : rightInfo.isBST; 77 | boolean leftMaxLessX = leftInfo == null ? true : (leftInfo.max < x.val); 78 | boolean rightMinMoreX = rightInfo == null ? true : (rightInfo.min > x.val); 79 | if (leftIsBst && rightIsBst && leftMaxLessX && rightMinMoreX) { 80 | isBST = true; 81 | } 82 | return new Info(isBST, max, min); 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /src/class01/Code05_BubbleSort.java: -------------------------------------------------------------------------------- 1 | package class01; 2 | 3 | import java.util.Arrays; 4 | 5 | public class Code05_BubbleSort { 6 | 7 | public static void bubbleSort(int[] arr) { 8 | if (arr == null || arr.length < 2) { 9 | return; 10 | } 11 | for (int end = arr.length - 1; end > 0; end--) { 12 | for (int i = 0; i < end; i++) { 13 | if (arr[i] > arr[i + 1]) { 14 | swap(arr, i, i + 1); 15 | } 16 | } 17 | } 18 | } 19 | 20 | // 交换arr的i和j位置上的值 21 | public static void swap(int[] arr, int i, int j) { 22 | int tmp = arr[i]; 23 | arr[i] = arr[j]; 24 | arr[j] = tmp; 25 | } 26 | 27 | // for test 28 | public static void comparator(int[] arr) { 29 | Arrays.sort(arr); 30 | } 31 | 32 | // for test 33 | public static int[] generateRandomArray(int maxSize, int maxValue) { 34 | int[] arr = new int[(int) ((maxSize + 1) * Math.random())]; 35 | for (int i = 0; i < arr.length; i++) { 36 | arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random()); 37 | } 38 | return arr; 39 | } 40 | 41 | // for test 42 | public static int[] copyArray(int[] arr) { 43 | if (arr == null) { 44 | return null; 45 | } 46 | int[] res = new int[arr.length]; 47 | for (int i = 0; i < arr.length; i++) { 48 | res[i] = arr[i]; 49 | } 50 | return res; 51 | } 52 | 53 | // for test 54 | public static boolean isEqual(int[] arr1, int[] arr2) { 55 | if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) { 56 | return false; 57 | } 58 | if (arr1 == null && arr2 == null) { 59 | return true; 60 | } 61 | if (arr1.length != arr2.length) { 62 | return false; 63 | } 64 | for (int i = 0; i < arr1.length; i++) { 65 | if (arr1[i] != arr2[i]) { 66 | return false; 67 | } 68 | } 69 | return true; 70 | } 71 | 72 | // for test 73 | public static void printArray(int[] arr) { 74 | if (arr == null) { 75 | return; 76 | } 77 | for (int i = 0; i < arr.length; i++) { 78 | System.out.print(arr[i] + " "); 79 | } 80 | System.out.println(); 81 | } 82 | 83 | // for test 84 | public static void main(String[] args) { 85 | int testTime = 500000; 86 | int maxSize = 100; 87 | int maxValue = 100; 88 | boolean succeed = true; 89 | for (int i = 0; i < testTime; i++) { 90 | int[] arr1 = generateRandomArray(maxSize, maxValue); 91 | int[] arr2 = copyArray(arr1); 92 | bubbleSort(arr1); 93 | comparator(arr2); 94 | if (!isEqual(arr1, arr2)) { 95 | succeed = false; 96 | break; 97 | } 98 | } 99 | System.out.println(succeed ? "Nice!" : "Fucking fucked!"); 100 | 101 | int[] arr = generateRandomArray(maxSize, maxValue); 102 | printArray(arr); 103 | bubbleSort(arr); 104 | printArray(arr); 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /src/class03/Code05_HashMapTreeMap.java: -------------------------------------------------------------------------------- 1 | package class03; 2 | 3 | import java.util.HashMap; 4 | import java.util.TreeMap; 5 | 6 | public class Code05_HashMapTreeMap { 7 | 8 | public static class Node { 9 | public int value; 10 | 11 | public Node(int v) { 12 | value = v; 13 | } 14 | } 15 | 16 | // (K V)表 17 | public static void main(String[] args) { 18 | HashMap map = new HashMap<>(); 19 | map.put("zuochengyun", "我是左程云"); 20 | System.out.println(map.containsKey("zuochengyun")); 21 | System.out.println(map.containsKey("zuo")); 22 | System.out.println(map.get("zuochengyun")); 23 | 24 | map.put("zuochengyun", "他是左程云"); 25 | System.out.println(map.get("zuochengyun")); 26 | 27 | // map.remove("zuochengyun"); 28 | // System.out.println(map.containsKey("zuochengyun")); 29 | // System.out.println(map.get("zuochengyun")); 30 | 31 | String test1 = "zuochengyun"; 32 | String test2 = "zuochengyun"; 33 | System.out.println(map.containsKey(test1)); 34 | System.out.println(map.containsKey(test2)); 35 | 36 | HashMap map2 = new HashMap<>(); 37 | map2.put(1234567, "我是1234567"); 38 | 39 | Integer a = 1234567; 40 | Integer b = 1234567; 41 | 42 | System.out.println(a == b); 43 | System.out.println(map2.containsKey(a)); 44 | System.out.println(map2.containsKey(b)); 45 | 46 | Node node1 = new Node(1); 47 | Node node2 = new Node(1); 48 | HashMap map3 = new HashMap<>(); 49 | map3.put(node1, "我进来了!"); 50 | System.out.println(map3.containsKey(node1)); 51 | System.out.println(map3.containsKey(node2)); 52 | 53 | System.out.println("==================="); 54 | 55 | TreeMap treeMap1 = new TreeMap<>(); 56 | 57 | treeMap1.put(3, "我是3"); 58 | treeMap1.put(0, "我是3"); 59 | treeMap1.put(7, "我是3"); 60 | treeMap1.put(2, "我是3"); 61 | treeMap1.put(5, "我是3"); 62 | treeMap1.put(9, "我是3"); 63 | 64 | System.out.println(treeMap1.containsKey(7)); 65 | System.out.println(treeMap1.containsKey(6)); 66 | System.out.println(treeMap1.get(3)); 67 | 68 | treeMap1.put(3, "他是3"); 69 | System.out.println(treeMap1.get(3)); 70 | 71 | treeMap1.remove(3); 72 | System.out.println(treeMap1.get(3)); 73 | 74 | System.out.println(treeMap1.firstKey()); 75 | System.out.println(treeMap1.lastKey()); 76 | // <=5 离5最近的key告诉我 77 | System.out.println(treeMap1.floorKey(5)); 78 | // <=6 离6最近的key告诉我 79 | System.out.println(treeMap1.floorKey(6)); 80 | // >=5 离5最近的key告诉我 81 | System.out.println(treeMap1.ceilingKey(5)); 82 | // >=6 离6最近的key告诉我 83 | System.out.println(treeMap1.ceilingKey(6)); 84 | 85 | // Node node3 = new Node(3); 86 | // Node node4 = new Node(4); 87 | // TreeMap treeMap2 = new TreeMap<>(); 88 | // treeMap2.put(node3, "我是node3"); 89 | // treeMap2.put(node4, "我是node4"); 90 | 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /src/class06/ShowComparator.java: -------------------------------------------------------------------------------- 1 | package class06; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.Comparator; 6 | 7 | public class ShowComparator { 8 | 9 | public static class Student { 10 | public String name; 11 | public int id; 12 | public int age; 13 | 14 | public Student(String name, int id, int age) { 15 | this.name = name; 16 | this.id = id; 17 | this.age = age; 18 | } 19 | } 20 | 21 | // 谁id大,谁放前! 22 | public static class IdComparator implements Comparator { 23 | 24 | // 如果返回负数,认为第一个参数应该排在前面 25 | // 如果返回正数,认为第二个参数应该排在前面 26 | // 如果返回0,认为谁放前面无所谓 27 | @Override 28 | public int compare(Student o1, Student o2) { 29 | if (o1.id < o2.id) { 30 | return 1; 31 | } else if (o2.id < o1.id) { 32 | return -1; 33 | } else { 34 | return 0; 35 | } 36 | } 37 | } 38 | 39 | // 谁age大,谁放前! 40 | public static class AgeComparator implements Comparator { 41 | 42 | // 如果返回负数,认为第一个参数应该排在前面 43 | // 如果返回正数,认为第二个参数应该排在前面 44 | // 如果返回0,认为谁放前面无所谓 45 | @Override 46 | public int compare(Student o1, Student o2) { 47 | if (o1.age < o2.age) { 48 | return 1; 49 | } else if (o2.age < o1.age) { 50 | return -1; 51 | } else { 52 | return 0; 53 | } 54 | } 55 | } 56 | 57 | public static void printArray(int[] arr) { 58 | for (int i = 0; i < arr.length; i++) { 59 | System.out.print(arr[i] + " "); 60 | } 61 | System.out.println(); 62 | } 63 | 64 | public static void printStudents(Student[] students) { 65 | for (int i = 0; i < students.length; i++) { 66 | System.out.println(students[i].name + ", " + students[i].id + ", " + students[i].age); 67 | } 68 | } 69 | 70 | public static void main(String[] args) { 71 | int[] arr = { 8, 1, 4, 1, 6, 8, 4, 1, 5, 8, 2, 3, 0 }; 72 | printArray(arr); 73 | Arrays.sort(arr); 74 | printArray(arr); 75 | 76 | Student s1 = new Student("张三", 5, 27); 77 | Student s2 = new Student("李四", 1, 17); 78 | Student s3 = new Student("王五", 4, 29); 79 | Student s4 = new Student("赵六", 3, 9); 80 | Student s5 = new Student("左七", 2, 34); 81 | 82 | Student[] students = { s1, s2, s3, s4, s5 }; 83 | printStudents(students); 84 | System.out.println("======="); 85 | Arrays.sort(students, new IdComparator()); 86 | printStudents(students); 87 | System.out.println("======="); 88 | 89 | ArrayList arrList = new ArrayList<>(); 90 | arrList.add(s1); 91 | arrList.add(s2); 92 | arrList.add(s3); 93 | arrList.add(s4); 94 | arrList.add(s5); 95 | for (Student s : arrList) { 96 | System.out.println(s.name + ", " + s.id + ", " + s.age); 97 | } 98 | System.out.println("======="); 99 | arrList.sort(new AgeComparator()); 100 | for (Student s : arrList) { 101 | System.out.println(s.name + ", " + s.id + ", " + s.age); 102 | } 103 | 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /src/class01/Code04_SelectionSort.java: -------------------------------------------------------------------------------- 1 | package class01; 2 | 3 | import java.util.Arrays; 4 | 5 | public class Code04_SelectionSort { 6 | 7 | public static void selectionSort(int[] arr) { 8 | if (arr == null || arr.length < 2) { 9 | return; 10 | } 11 | for (int i = 0; i < arr.length - 1; i++) { 12 | int minIndex = i; 13 | for (int j = i + 1; j < arr.length; j++) { 14 | if(arr[j] < arr[minIndex]) { 15 | minIndex = j; 16 | } 17 | } 18 | swap(arr, i, minIndex); 19 | } 20 | } 21 | 22 | public static void swap(int[] arr, int i, int j) { 23 | int tmp = arr[i]; 24 | arr[i] = arr[j]; 25 | arr[j] = tmp; 26 | } 27 | 28 | // for test 29 | public static void comparator(int[] arr) { 30 | Arrays.sort(arr); 31 | } 32 | 33 | // for test 34 | public static int[] generateRandomArray(int maxSize, int maxValue) { 35 | // Math.random() [0,1) 36 | // Math.random() * N [0,N) 37 | // (int)(Math.random() * N) [0, N-1] 38 | int[] arr = new int[(int) ((maxSize + 1) * Math.random())]; 39 | for (int i = 0; i < arr.length; i++) { 40 | // [-? , +?] 41 | arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random()); 42 | } 43 | return arr; 44 | } 45 | 46 | // for test 47 | public static int[] copyArray(int[] arr) { 48 | if (arr == null) { 49 | return null; 50 | } 51 | int[] res = new int[arr.length]; 52 | for (int i = 0; i < arr.length; i++) { 53 | res[i] = arr[i]; 54 | } 55 | return res; 56 | } 57 | 58 | // for test 59 | public static boolean isEqual(int[] arr1, int[] arr2) { 60 | if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) { 61 | return false; 62 | } 63 | if (arr1 == null && arr2 == null) { 64 | return true; 65 | } 66 | if (arr1.length != arr2.length) { 67 | return false; 68 | } 69 | for (int i = 0; i < arr1.length; i++) { 70 | if (arr1[i] != arr2[i]) { 71 | return false; 72 | } 73 | } 74 | return true; 75 | } 76 | 77 | // for test 78 | public static void printArray(int[] arr) { 79 | if (arr == null) { 80 | return; 81 | } 82 | for (int i = 0; i < arr.length; i++) { 83 | System.out.print(arr[i] + " "); 84 | } 85 | System.out.println(); 86 | } 87 | 88 | // for test 89 | public static void main(String[] args) { 90 | int testTime = 500000; 91 | int maxSize = 100; 92 | int maxValue = 100; 93 | boolean succeed = true; 94 | for (int i = 0; i < testTime; i++) { 95 | int[] arr1 = generateRandomArray(maxSize, maxValue); 96 | int[] arr2 = copyArray(arr1); 97 | selectionSort(arr1); 98 | comparator(arr2); 99 | if (!isEqual(arr1, arr2)) { 100 | succeed = false; 101 | printArray(arr1); 102 | printArray(arr2); 103 | break; 104 | } 105 | } 106 | System.out.println(succeed ? "Nice!" : "Fucking fucked!"); 107 | 108 | int[] arr = generateRandomArray(maxSize, maxValue); 109 | printArray(arr); 110 | selectionSort(arr); 111 | printArray(arr); 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /src/class01/Code06_InsertionSort.java: -------------------------------------------------------------------------------- 1 | package class01; 2 | 3 | import java.util.Arrays; 4 | 5 | public class Code06_InsertionSort { 6 | 7 | public static void insertionSort(int[] arr) { 8 | if (arr == null || arr.length < 2) { 9 | return; 10 | } 11 | for (int i = 1; i < arr.length; i++) { // 0 ~ i 做到有序 12 | for (int j = i - 1; j >= 0 && arr[j] > arr[j + 1]; j--) { 13 | swap(arr, j, j + 1); 14 | } 15 | } 16 | } 17 | 18 | // i和j,数交换 19 | public static void swap(int[] arr, int i, int j) { 20 | int tmp = arr[i]; 21 | arr[i] = arr[j]; 22 | arr[j] = tmp; 23 | } 24 | 25 | // for test 26 | public static void comparator(int[] arr) { 27 | Arrays.sort(arr); 28 | } 29 | 30 | // for test 31 | public static int[] generateRandomArray(int maxSize, int maxValue) { 32 | // Math.random() -> [0,1) 所有的小数,等概率返回一个 33 | // Math.random() * N -> [0,N) 所有小数,等概率返回一个 34 | // (int)(Math.random() * N) -> [0,N-1] 所有的整数,等概率返回一个 35 | int[] arr = new int[(int) ((maxSize + 1) * Math.random())]; // 长度随机 36 | for (int i = 0; i < arr.length; i++) { 37 | arr[i] = (int) ((maxValue + 1) * Math.random()) 38 | - (int) (maxValue * Math.random()); 39 | } 40 | return arr; 41 | } 42 | 43 | // for test 44 | public static int[] copyArray(int[] arr) { 45 | if (arr == null) { 46 | return null; 47 | } 48 | int[] res = new int[arr.length]; 49 | for (int i = 0; i < arr.length; i++) { 50 | res[i] = arr[i]; 51 | } 52 | return res; 53 | } 54 | 55 | // for test 56 | public static boolean isEqual(int[] arr1, int[] arr2) { 57 | if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) { 58 | return false; 59 | } 60 | if (arr1 == null && arr2 == null) { 61 | return true; 62 | } 63 | if (arr1.length != arr2.length) { 64 | return false; 65 | } 66 | for (int i = 0; i < arr1.length; i++) { 67 | if (arr1[i] != arr2[i]) { 68 | return false; 69 | } 70 | } 71 | return true; 72 | } 73 | 74 | // for test 75 | public static void printArray(int[] arr) { 76 | if (arr == null) { 77 | return; 78 | } 79 | for (int i = 0; i < arr.length; i++) { 80 | System.out.print(arr[i] + " "); 81 | } 82 | System.out.println(); 83 | } 84 | 85 | // for test 86 | public static void main(String[] args) { 87 | int testTime = 500000; 88 | int maxSize = 100; // 随机数组的长度0~100 89 | int maxValue = 100;// 值:-100~100 90 | boolean succeed = true; 91 | for (int i = 0; i < testTime; i++) { 92 | int[] arr1 = generateRandomArray(maxSize, maxValue); 93 | int[] arr2 = copyArray(arr1); 94 | insertionSort(arr1); 95 | comparator(arr2); 96 | if (!isEqual(arr1, arr2)) { 97 | // 打印arr1 98 | // 打印arr2 99 | succeed = false; 100 | break; 101 | } 102 | } 103 | System.out.println(succeed ? "Nice!" : "Fucking fucked!"); 104 | 105 | int[] arr = generateRandomArray(maxSize, maxValue); 106 | printArray(arr); 107 | insertionSort(arr); 108 | printArray(arr); 109 | } 110 | 111 | } 112 | -------------------------------------------------------------------------------- /src/class04/Code03_DoubleLinkedListToDeque.java: -------------------------------------------------------------------------------- 1 | package class04; 2 | 3 | import java.util.Deque; 4 | import java.util.LinkedList; 5 | 6 | public class Code03_DoubleLinkedListToDeque { 7 | 8 | public static class Node { 9 | public V value; 10 | public Node last; 11 | public Node next; 12 | 13 | public Node(V v) { 14 | value = v; 15 | last = null; 16 | next = null; 17 | } 18 | } 19 | 20 | public static class MyDeque { 21 | private Node head; 22 | private Node tail; 23 | private int size; 24 | 25 | public MyDeque() { 26 | head = null; 27 | tail = null; 28 | size = 0; 29 | } 30 | 31 | public boolean isEmpty() { 32 | return size == 0; 33 | } 34 | 35 | public int size() { 36 | return size; 37 | } 38 | 39 | public void pushHead(V value) { 40 | Node cur = new Node<>(value); 41 | if (head == null) { 42 | head = cur; 43 | tail = cur; 44 | } else { 45 | cur.next = head; 46 | head.last = cur; 47 | head = cur; 48 | } 49 | size++; 50 | } 51 | 52 | public void pushTail(V value) { 53 | Node cur = new Node<>(value); 54 | if (head == null) { 55 | head = cur; 56 | tail = cur; 57 | } else { 58 | tail.next = cur; 59 | cur.last = tail; 60 | tail = cur; 61 | } 62 | size++; 63 | } 64 | 65 | public V pollHead() { 66 | V ans = null; 67 | if (head == null) { 68 | return ans; 69 | } 70 | size--; 71 | ans = head.value; 72 | if (head == tail) { 73 | head = null; 74 | tail = null; 75 | } else { 76 | head = head.next; 77 | head.last = null; 78 | } 79 | return ans; 80 | } 81 | 82 | public V pollTail() { 83 | V ans = null; 84 | if (head == null) { 85 | return ans; 86 | } 87 | size--; 88 | ans = tail.value; 89 | if (head == tail) { 90 | head = null; 91 | tail = null; 92 | } else { 93 | tail = tail.last; 94 | tail.next = null; 95 | } 96 | return ans; 97 | } 98 | 99 | public V peekHead() { 100 | V ans = null; 101 | if (head != null) { 102 | ans = head.value; 103 | } 104 | return ans; 105 | } 106 | 107 | public V peekTail() { 108 | V ans = null; 109 | if (tail != null) { 110 | ans = tail.value; 111 | } 112 | return ans; 113 | } 114 | 115 | } 116 | 117 | public static void testDeque() { 118 | MyDeque myDeque = new MyDeque<>(); 119 | Deque test = new LinkedList<>(); 120 | int testTime = 5000000; 121 | int maxValue = 200000000; 122 | System.out.println("测试开始!"); 123 | for (int i = 0; i < testTime; i++) { 124 | if (myDeque.isEmpty() != test.isEmpty()) { 125 | System.out.println("Oops!"); 126 | } 127 | if (myDeque.size() != test.size()) { 128 | System.out.println("Oops!"); 129 | } 130 | double decide = Math.random(); 131 | if (decide < 0.33) { 132 | int num = (int) (Math.random() * maxValue); 133 | if (Math.random() < 0.5) { 134 | myDeque.pushHead(num); 135 | test.addFirst(num); 136 | } else { 137 | myDeque.pushTail(num); 138 | test.addLast(num); 139 | } 140 | } else if (decide < 0.66) { 141 | if (!myDeque.isEmpty()) { 142 | int num1 = 0; 143 | int num2 = 0; 144 | if (Math.random() < 0.5) { 145 | num1 = myDeque.pollHead(); 146 | num2 = test.pollFirst(); 147 | } else { 148 | num1 = myDeque.pollTail(); 149 | num2 = test.pollLast(); 150 | } 151 | if (num1 != num2) { 152 | System.out.println("Oops!"); 153 | } 154 | } 155 | } else { 156 | if (!myDeque.isEmpty()) { 157 | int num1 = 0; 158 | int num2 = 0; 159 | if (Math.random() < 0.5) { 160 | num1 = myDeque.peekHead(); 161 | num2 = test.peekFirst(); 162 | } else { 163 | num1 = myDeque.peekTail(); 164 | num2 = test.peekLast(); 165 | } 166 | if (num1 != num2) { 167 | System.out.println("Oops!"); 168 | } 169 | } 170 | } 171 | } 172 | if (myDeque.size() != test.size()) { 173 | System.out.println("Oops!"); 174 | } 175 | while (!myDeque.isEmpty()) { 176 | int num1 = myDeque.pollHead(); 177 | int num2 = test.pollFirst(); 178 | if (num1 != num2) { 179 | System.out.println("Oops!"); 180 | } 181 | } 182 | System.out.println("测试结束!"); 183 | } 184 | 185 | public static void main(String[] args) { 186 | testDeque(); 187 | } 188 | 189 | } 190 | -------------------------------------------------------------------------------- /src/class08/Code02_MergeSort.java: -------------------------------------------------------------------------------- 1 | package class08; 2 | 3 | // 可以去体系学习班学习 4 | public class Code02_MergeSort { 5 | 6 | // 递归方法实现 7 | public static void mergeSort1(int[] arr) { 8 | if (arr == null || arr.length < 2) { 9 | return; 10 | } 11 | process(arr, 0, arr.length - 1); 12 | } 13 | 14 | // arr[L...R]范围上,请让这个范围上的数,有序! 15 | public static void process(int[] arr, int L, int R) { 16 | if (L == R) { 17 | return; 18 | } 19 | // int mid = (L + R) / 2 20 | int mid = L + ((R - L) >> 1); 21 | process(arr, L, mid); 22 | process(arr, mid + 1, R); 23 | merge(arr, L, mid, R); 24 | } 25 | 26 | public static void merge(int[] arr, int L, int M, int R) { 27 | int[] help = new int[R - L + 1]; 28 | int i = 0; 29 | int p1 = L; 30 | int p2 = M + 1; 31 | while (p1 <= M && p2 <= R) { 32 | help[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++]; 33 | } 34 | // 要么p1越界,要么p2越界 35 | // 不可能出现:共同越界 36 | while (p1 <= M) { 37 | help[i++] = arr[p1++]; 38 | } 39 | while (p2 <= R) { 40 | help[i++] = arr[p2++]; 41 | } 42 | for (i = 0; i < help.length; i++) { 43 | arr[L + i] = help[i]; 44 | } 45 | } 46 | 47 | public static void mergeSort2(int[] arr) { 48 | if (arr == null || arr.length < 2) { 49 | return; 50 | } 51 | int step = 1; 52 | int N = arr.length; 53 | while (step < N) { 54 | int L = 0; 55 | while (L < N) { 56 | int M = 0; 57 | if (N - L >= step) { 58 | M = L + step - 1; 59 | } else { 60 | M = N - 1; 61 | } 62 | if (M == N - 1) { 63 | break; 64 | } 65 | int R = 0; 66 | if (N - 1 - M >= step) { 67 | R = M + step; 68 | } else { 69 | R = N - 1; 70 | } 71 | merge(arr, L, M, R); 72 | if (R == N - 1) { 73 | break; 74 | } else { 75 | L = R + 1; 76 | } 77 | } 78 | if (step > N / 2) { 79 | break; 80 | } 81 | step *= 2; 82 | } 83 | 84 | } 85 | 86 | // 非递归方法实现 87 | // public static void mergeSort2(int[] arr) { 88 | // if (arr == null || arr.length < 2) { 89 | // return; 90 | // } 91 | // int N = arr.length; 92 | // int mergeSize = 1; 93 | // while (mergeSize < N) { 94 | // int L = 0; 95 | // while (L < N) { 96 | // if (mergeSize >= N - L) { 97 | // break; 98 | // } 99 | // int M = L + mergeSize - 1; 100 | // int R = M + Math.min(mergeSize, N - M - 1); 101 | // merge(arr, L, M, R); 102 | // L = R + 1; 103 | // } 104 | // if (mergeSize > N / 2) { 105 | // break; 106 | // } 107 | // mergeSize <<= 1; 108 | // } 109 | // } 110 | 111 | // for test 112 | public static int[] generateRandomArray(int maxSize, int maxValue) { 113 | int[] arr = new int[(int) ((maxSize + 1) * Math.random())]; 114 | for (int i = 0; i < arr.length; i++) { 115 | arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random()); 116 | } 117 | return arr; 118 | } 119 | 120 | // for test 121 | public static int[] copyArray(int[] arr) { 122 | if (arr == null) { 123 | return null; 124 | } 125 | int[] res = new int[arr.length]; 126 | for (int i = 0; i < arr.length; i++) { 127 | res[i] = arr[i]; 128 | } 129 | return res; 130 | } 131 | 132 | // for test 133 | public static boolean isEqual(int[] arr1, int[] arr2) { 134 | if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) { 135 | return false; 136 | } 137 | if (arr1 == null && arr2 == null) { 138 | return true; 139 | } 140 | if (arr1.length != arr2.length) { 141 | return false; 142 | } 143 | for (int i = 0; i < arr1.length; i++) { 144 | if (arr1[i] != arr2[i]) { 145 | return false; 146 | } 147 | } 148 | return true; 149 | } 150 | 151 | // for test 152 | public static void printArray(int[] arr) { 153 | if (arr == null) { 154 | return; 155 | } 156 | for (int i = 0; i < arr.length; i++) { 157 | System.out.print(arr[i] + " "); 158 | } 159 | System.out.println(); 160 | } 161 | 162 | // for test 163 | public static void main(String[] args) { 164 | int testTime = 500000; 165 | int maxSize = 100; 166 | int maxValue = 100; 167 | System.out.println("测试开始"); 168 | for (int i = 0; i < testTime; i++) { 169 | int[] arr1 = generateRandomArray(maxSize, maxValue); 170 | int[] arr2 = copyArray(arr1); 171 | mergeSort1(arr1); 172 | mergeSort2(arr2); 173 | if (!isEqual(arr1, arr2)) { 174 | System.out.println("出错了!"); 175 | printArray(arr1); 176 | printArray(arr2); 177 | break; 178 | } 179 | } 180 | System.out.println("测试结束"); 181 | } 182 | 183 | } 184 | -------------------------------------------------------------------------------- /src/class04/Code02_LinkedListToQueueAndStack.java: -------------------------------------------------------------------------------- 1 | package class04; 2 | 3 | import java.util.LinkedList; 4 | import java.util.Queue; 5 | import java.util.Stack; 6 | 7 | public class Code02_LinkedListToQueueAndStack { 8 | 9 | public static class Node { 10 | public V value; 11 | public Node next; 12 | 13 | public Node(V v) { 14 | value = v; 15 | next = null; 16 | } 17 | } 18 | 19 | public static class MyQueue { 20 | private Node head; 21 | private Node tail; 22 | private int size; 23 | 24 | public MyQueue() { 25 | head = null; 26 | tail = null; 27 | size = 0; 28 | } 29 | 30 | public boolean isEmpty() { 31 | return size == 0; 32 | } 33 | 34 | public int size() { 35 | return size; 36 | } 37 | 38 | public void offer(V value) { 39 | Node cur = new Node(value); 40 | if (tail == null) { 41 | head = cur; 42 | tail = cur; 43 | } else { 44 | tail.next = cur; 45 | tail = cur; 46 | } 47 | size++; 48 | } 49 | 50 | // C/C++的同学需要做节点析构的工作 51 | public V poll() { 52 | V ans = null; 53 | if (head != null) { 54 | ans = head.value; 55 | head = head.next; 56 | size--; 57 | } 58 | if (head == null) { 59 | tail = null; 60 | } 61 | return ans; 62 | } 63 | 64 | // C/C++的同学需要做节点析构的工作 65 | public V peek() { 66 | V ans = null; 67 | if (head != null) { 68 | ans = head.value; 69 | } 70 | return ans; 71 | } 72 | 73 | } 74 | 75 | public static class MyStack { 76 | private Node head; 77 | private int size; 78 | 79 | public MyStack() { 80 | head = null; 81 | size = 0; 82 | } 83 | 84 | public boolean isEmpty() { 85 | return size == 0; 86 | } 87 | 88 | public int size() { 89 | return size; 90 | } 91 | 92 | public void push(V value) { 93 | Node cur = new Node<>(value); 94 | if (head == null) { 95 | head = cur; 96 | } else { 97 | cur.next = head; 98 | head = cur; 99 | } 100 | size++; 101 | } 102 | 103 | public V pop() { 104 | V ans = null; 105 | if (head != null) { 106 | ans = head.value; 107 | head = head.next; 108 | size--; 109 | } 110 | return ans; 111 | } 112 | 113 | public V peek() { 114 | return head != null ? head.value : null; 115 | } 116 | 117 | } 118 | 119 | public static void testQueue() { 120 | MyQueue myQueue = new MyQueue<>(); 121 | Queue test = new LinkedList<>(); 122 | int testTime = 5000000; 123 | int maxValue = 200000000; 124 | System.out.println("测试开始!"); 125 | for (int i = 0; i < testTime; i++) { 126 | if (myQueue.isEmpty() != test.isEmpty()) { 127 | System.out.println("Oops!"); 128 | } 129 | if (myQueue.size() != test.size()) { 130 | System.out.println("Oops!"); 131 | } 132 | double decide = Math.random(); 133 | if (decide < 0.33) { 134 | int num = (int) (Math.random() * maxValue); 135 | myQueue.offer(num); 136 | test.offer(num); 137 | } else if (decide < 0.66) { 138 | if (!myQueue.isEmpty()) { 139 | int num1 = myQueue.poll(); 140 | int num2 = test.poll(); 141 | if (num1 != num2) { 142 | System.out.println("Oops!"); 143 | } 144 | } 145 | } else { 146 | if (!myQueue.isEmpty()) { 147 | int num1 = myQueue.peek(); 148 | int num2 = test.peek(); 149 | if (num1 != num2) { 150 | System.out.println("Oops!"); 151 | } 152 | } 153 | } 154 | } 155 | if (myQueue.size() != test.size()) { 156 | System.out.println("Oops!"); 157 | } 158 | while (!myQueue.isEmpty()) { 159 | int num1 = myQueue.poll(); 160 | int num2 = test.poll(); 161 | if (num1 != num2) { 162 | System.out.println("Oops!"); 163 | } 164 | } 165 | System.out.println("测试结束!"); 166 | } 167 | 168 | public static void testStack() { 169 | MyStack myStack = new MyStack<>(); 170 | Stack test = new Stack<>(); 171 | int testTime = 5000000; 172 | int maxValue = 200000000; 173 | System.out.println("测试开始!"); 174 | for (int i = 0; i < testTime; i++) { 175 | if (myStack.isEmpty() != test.isEmpty()) { 176 | System.out.println("Oops!"); 177 | } 178 | if (myStack.size() != test.size()) { 179 | System.out.println("Oops!"); 180 | } 181 | double decide = Math.random(); 182 | if (decide < 0.33) { 183 | int num = (int) (Math.random() * maxValue); 184 | myStack.push(num); 185 | test.push(num); 186 | } else if (decide < 0.66) { 187 | if (!myStack.isEmpty()) { 188 | int num1 = myStack.pop(); 189 | int num2 = test.pop(); 190 | if (num1 != num2) { 191 | System.out.println("Oops!"); 192 | } 193 | } 194 | } else { 195 | if (!myStack.isEmpty()) { 196 | int num1 = myStack.peek(); 197 | int num2 = test.peek(); 198 | if (num1 != num2) { 199 | System.out.println("Oops!"); 200 | } 201 | } 202 | } 203 | } 204 | if (myStack.size() != test.size()) { 205 | System.out.println("Oops!"); 206 | } 207 | while (!myStack.isEmpty()) { 208 | int num1 = myStack.pop(); 209 | int num2 = test.pop(); 210 | if (num1 != num2) { 211 | System.out.println("Oops!"); 212 | } 213 | } 214 | System.out.println("测试结束!"); 215 | } 216 | 217 | public static void main(String[] args) { 218 | testQueue(); 219 | testStack(); 220 | } 221 | 222 | } 223 | -------------------------------------------------------------------------------- /src/class02/Code02_RandToRand.java: -------------------------------------------------------------------------------- 1 | package class02; 2 | 3 | public class Code02_RandToRand { 4 | 5 | // 此函数只能用,不能修改 6 | // 等概率返回1~5 7 | public static int f() { 8 | return (int) (Math.random() * 5) + 1; 9 | } 10 | 11 | // 等概率得到0和1 12 | public static int a() { 13 | int ans = 0; 14 | do { 15 | ans = f(); 16 | } while (ans == 3); 17 | return ans < 3 ? 0 : 1; 18 | } 19 | 20 | // 等概率返回0~6 21 | public static int b() { 22 | int ans = 0; 23 | do { 24 | ans = (a() << 2) + (a() << 1) + a(); 25 | } while (ans == 7); 26 | return ans; 27 | } 28 | 29 | // 等概率返回1~7 30 | public static int c() { 31 | return b() + 1; 32 | } 33 | 34 | // 这个结构是唯一的随机机制 35 | // 你只能初始化并使用,不可修改 36 | public static class RandomBox { 37 | private final int min; 38 | private final int max; 39 | 40 | // 初始化时请一定不要让mi==ma 41 | public RandomBox(int mi, int ma) { 42 | min = mi; 43 | max = ma; 44 | } 45 | 46 | // 13 ~ 17 47 | // 13 + [0,4] 48 | public int random() { 49 | return min + (int) (Math.random() * (max - min + 1)); 50 | } 51 | 52 | public int min() { 53 | return min; 54 | } 55 | 56 | public int max() { 57 | return max; 58 | } 59 | } 60 | 61 | // 利用条件RandomBox,如何等概率返回0和1 62 | public static int rand01(RandomBox randomBox) { 63 | int min = randomBox.min(); 64 | int max = randomBox.max(); 65 | // min ~ max 66 | int size = max - min + 1; 67 | // size是不是奇数,odd 奇数 68 | boolean odd = (size & 1) != 0; 69 | int mid = size / 2; 70 | int ans = 0; 71 | do { 72 | ans = randomBox.random() - min; 73 | } while (odd && ans == mid); 74 | return ans < mid ? 0 : 1; 75 | } 76 | 77 | // 给你一个RandomBox,这是唯一能借助的随机机制 78 | // 等概率返回from~to范围上任何一个数 79 | // 要求from<=to 80 | public static int random(RandomBox randomBox, int from, int to) { 81 | if (from == to) { 82 | return from; 83 | } 84 | // 3 ~ 9 85 | // 0 ~ 6 86 | // 0 ~ range 87 | int range = to - from; 88 | int num = 1; 89 | // 求0~range需要几个2进制位 90 | while ((1 << num) - 1 < range) { 91 | num++; 92 | } 93 | 94 | // 我们一共需要num位 95 | // 最终的累加和,首先+0位上是1还是0,1位上是1还是0,2位上是1还是0... 96 | int ans = 0; 97 | do { 98 | ans = 0; 99 | for (int i = 0; i < num; i++) { 100 | ans |= (rand01(randomBox) << i); 101 | } 102 | } while (ans > range); 103 | return ans + from; 104 | } 105 | 106 | public static void main(String[] args) { 107 | System.out.println("测试开始"); 108 | // Math.random() -> double -> [0,1) 109 | // 110 | 111 | int testTimes = 10000000; 112 | int count = 0; 113 | for (int i = 0; i < testTimes; i++) { 114 | if (Math.random() < 0.75) { 115 | count++; 116 | } 117 | } 118 | System.out.println((double) count / (double) testTimes); 119 | 120 | System.out.println("========="); 121 | 122 | // [0,1) -> [0,8) 123 | count = 0; 124 | for (int i = 0; i < testTimes; i++) { 125 | if (Math.random() * 8 < 5) { 126 | count++; 127 | } 128 | } 129 | System.out.println((double) count / (double) testTimes); 130 | System.out.println((double) 5 / (double) 8); 131 | 132 | int K = 9; 133 | // [0,K) -> [0,8] 134 | 135 | int[] counts = new int[9]; 136 | for (int i = 0; i < testTimes; i++) { 137 | int ans = (int) (Math.random() * K); // [0,K-1] 138 | counts[ans]++; 139 | } 140 | for (int i = 0; i < K; i++) { 141 | System.out.println(i + "这个数,出现了 " + counts[i] + " 次"); 142 | } 143 | 144 | System.out.println("========="); 145 | 146 | count = 0; 147 | double x = 0.17; 148 | for (int i = 0; i < testTimes; i++) { 149 | if (xToXPower2() < x) { 150 | count++; 151 | } 152 | } 153 | System.out.println((double) count / (double) testTimes); 154 | System.out.println((double) 1 - Math.pow((double) 1 - x, 2)); 155 | 156 | System.out.println("=========="); 157 | count = 0; 158 | for (int i = 0; i < testTimes; i++) { 159 | if (f2() == 0) { 160 | count++; 161 | } 162 | } 163 | System.out.println((double) count / (double) testTimes); 164 | 165 | System.out.println("=========="); 166 | 167 | counts = new int[8]; 168 | for (int i = 0; i < testTimes; i++) { 169 | int num = g(); 170 | counts[num]++; 171 | } 172 | for (int i = 0; i < 8; i++) { 173 | System.out.println(i + "这个数,出现了 " + counts[i] + " 次"); 174 | } 175 | 176 | } 177 | 178 | // 返回[0,1)的一个小数 179 | // 任意的x,x属于[0,1),[0,x)范围上的数出现概率由原来的x调整成x平方 180 | public static double xToXPower2() { 181 | return Math.min(Math.random(), Math.random()); 182 | } 183 | 184 | // lib里的,不能改! 185 | public static int f1() { 186 | return (int) (Math.random() * 5) + 1; 187 | } 188 | 189 | // 随机机制,只能用f1, 190 | // 等概率返回0和1 191 | public static int f2() { 192 | int ans = 0; 193 | do { 194 | ans = f1(); 195 | } while (ans == 3); 196 | return ans < 3 ? 0 : 1; 197 | } 198 | 199 | // 得到000 ~ 111 做到等概率 0 ~ 7等概率返回一个 200 | public static int f3() { 201 | return (f2() << 2) + (f2() << 1) + f2(); 202 | } 203 | 204 | // 0 ~ 6等概率返回一个 205 | public static int f4() { 206 | int ans = 0; 207 | do { 208 | ans = f3(); 209 | } while (ans == 7); 210 | return ans; 211 | } 212 | 213 | public static int g() { 214 | return f4() + 1; 215 | } 216 | 217 | // 你只能知道,x会以固定概率返回0和1,但是x的内容,你看不到! 218 | public static int x() { 219 | return Math.random() < 0.84 ? 0 : 1; 220 | } 221 | 222 | // 等概率返回0和1 223 | public static int y() { 224 | int ans = 0; 225 | do { 226 | ans = x(); 227 | } while (ans == x()); 228 | return ans; 229 | } 230 | 231 | } 232 | -------------------------------------------------------------------------------- /src/class04/Code01_ReverseList.java: -------------------------------------------------------------------------------- 1 | package class04; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Code01_ReverseList { 7 | 8 | public static class Node { 9 | public int value; 10 | public Node next; 11 | 12 | public Node(int data) { 13 | value = data; 14 | } 15 | } 16 | 17 | public static class DoubleNode { 18 | public int value; 19 | public DoubleNode last; 20 | public DoubleNode next; 21 | 22 | public DoubleNode(int data) { 23 | value = data; 24 | } 25 | } 26 | 27 | public static Node reverseLinkedList(Node head) { 28 | Node pre = null; 29 | Node next = null; 30 | while (head != null) { 31 | next = head.next; 32 | head.next = pre; 33 | pre = head; 34 | head = next; 35 | } 36 | return pre; 37 | } 38 | 39 | public static DoubleNode reverseDoubleList(DoubleNode head) { 40 | DoubleNode pre = null; 41 | DoubleNode next = null; 42 | while (head != null) { 43 | next = head.next; 44 | head.next = pre; 45 | head.last = next; 46 | pre = head; 47 | head = next; 48 | } 49 | return pre; 50 | } 51 | 52 | public static Node testReverseLinkedList(Node head) { 53 | if (head == null) { 54 | return null; 55 | } 56 | ArrayList list = new ArrayList<>(); 57 | while (head != null) { 58 | list.add(head); 59 | head = head.next; 60 | } 61 | list.get(0).next = null; 62 | int N = list.size(); 63 | for (int i = 1; i < N; i++) { 64 | list.get(i).next = list.get(i - 1); 65 | } 66 | return list.get(N - 1); 67 | } 68 | 69 | public static DoubleNode testReverseDoubleList(DoubleNode head) { 70 | if (head == null) { 71 | return null; 72 | } 73 | ArrayList list = new ArrayList<>(); 74 | while (head != null) { 75 | list.add(head); 76 | head = head.next; 77 | } 78 | list.get(0).next = null; 79 | DoubleNode pre = list.get(0); 80 | int N = list.size(); 81 | for (int i = 1; i < N; i++) { 82 | DoubleNode cur = list.get(i); 83 | cur.last = null; 84 | cur.next = pre; 85 | pre.last = cur; 86 | pre = cur; 87 | } 88 | return list.get(N - 1); 89 | } 90 | 91 | // for test 92 | public static Node generateRandomLinkedList(int len, int value) { 93 | int size = (int) (Math.random() * (len + 1)); 94 | if (size == 0) { 95 | return null; 96 | } 97 | size--; 98 | Node head = new Node((int) (Math.random() * (value + 1))); 99 | Node pre = head; 100 | while (size != 0) { 101 | Node cur = new Node((int) (Math.random() * (value + 1))); 102 | pre.next = cur; 103 | pre = cur; 104 | size--; 105 | } 106 | return head; 107 | } 108 | 109 | // for test 110 | public static DoubleNode generateRandomDoubleList(int len, int value) { 111 | int size = (int) (Math.random() * (len + 1)); 112 | if (size == 0) { 113 | return null; 114 | } 115 | size--; 116 | DoubleNode head = new DoubleNode((int) (Math.random() * (value + 1))); 117 | DoubleNode pre = head; 118 | while (size != 0) { 119 | DoubleNode cur = new DoubleNode((int) (Math.random() * (value + 1))); 120 | pre.next = cur; 121 | cur.last = pre; 122 | pre = cur; 123 | size--; 124 | } 125 | return head; 126 | } 127 | 128 | // for test 129 | public static List getLinkedListOriginOrder(Node head) { 130 | List ans = new ArrayList<>(); 131 | while (head != null) { 132 | ans.add(head.value); 133 | head = head.next; 134 | } 135 | return ans; 136 | } 137 | 138 | // for test 139 | public static boolean checkLinkedListReverse(List origin, Node head) { 140 | for (int i = origin.size() - 1; i >= 0; i--) { 141 | if (!origin.get(i).equals(head.value)) { 142 | return false; 143 | } 144 | head = head.next; 145 | } 146 | return true; 147 | } 148 | 149 | // for test 150 | public static List getDoubleListOriginOrder(DoubleNode head) { 151 | List ans = new ArrayList<>(); 152 | while (head != null) { 153 | ans.add(head.value); 154 | head = head.next; 155 | } 156 | return ans; 157 | } 158 | 159 | // for test 160 | public static boolean checkDoubleListReverse(List origin, DoubleNode head) { 161 | DoubleNode end = null; 162 | for (int i = origin.size() - 1; i >= 0; i--) { 163 | if (!origin.get(i).equals(head.value)) { 164 | return false; 165 | } 166 | end = head; 167 | head = head.next; 168 | } 169 | for (int i = 0; i < origin.size(); i++) { 170 | if (!origin.get(i).equals(end.value)) { 171 | return false; 172 | } 173 | end = end.last; 174 | } 175 | return true; 176 | } 177 | 178 | 179 | public static void f(Node head) { 180 | head = head.next; 181 | } 182 | 183 | // for test 184 | public static void main(String[] args) { 185 | int len = 50; 186 | int value = 100; 187 | int testTime = 100000; 188 | System.out.println("test begin!"); 189 | for (int i = 0; i < testTime; i++) { 190 | Node node1 = generateRandomLinkedList(len, value); 191 | List list1 = getLinkedListOriginOrder(node1); 192 | node1 = reverseLinkedList(node1); 193 | if (!checkLinkedListReverse(list1, node1)) { 194 | System.out.println("Oops1!"); 195 | } 196 | 197 | Node node2 = generateRandomLinkedList(len, value); 198 | List list2 = getLinkedListOriginOrder(node2); 199 | node2 = testReverseLinkedList(node2); 200 | if (!checkLinkedListReverse(list2, node2)) { 201 | System.out.println("Oops2!"); 202 | } 203 | 204 | DoubleNode node3 = generateRandomDoubleList(len, value); 205 | List list3 = getDoubleListOriginOrder(node3); 206 | node3 = reverseDoubleList(node3); 207 | if (!checkDoubleListReverse(list3, node3)) { 208 | System.out.println("Oops3!"); 209 | } 210 | 211 | DoubleNode node4 = generateRandomDoubleList(len, value); 212 | List list4 = getDoubleListOriginOrder(node4); 213 | node4 = reverseDoubleList(node4); 214 | if (!checkDoubleListReverse(list4, node4)) { 215 | System.out.println("Oops4!"); 216 | } 217 | 218 | } 219 | System.out.println("test finish!"); 220 | 221 | } 222 | 223 | } -------------------------------------------------------------------------------- /src/class08/Code03_PartitionAndQuickSort.java: -------------------------------------------------------------------------------- 1 | package class08; 2 | 3 | import java.util.Stack; 4 | 5 | // 可以去体系学习班学习 6 | public class Code03_PartitionAndQuickSort { 7 | 8 | public static void splitNum1(int[] arr) { 9 | int lessEqualR = -1; 10 | int index = 0; 11 | int N = arr.length; 12 | while (index < N) { 13 | if (arr[index] <= arr[N - 1]) { 14 | swap(arr, ++lessEqualR, index++); 15 | } else { 16 | index++; 17 | } 18 | } 19 | } 20 | 21 | public static void splitNum2(int[] arr) { 22 | int N = arr.length; 23 | int lessR = -1; 24 | int moreL = N - 1; 25 | int index = 0; 26 | // arr[N-1] 27 | while (index < moreL) { 28 | if (arr[index] < arr[N - 1]) { 29 | swap(arr, ++lessR, index++); 30 | } else if (arr[index] > arr[N - 1]) { 31 | swap(arr, --moreL, index); 32 | } else { 33 | index++; 34 | } 35 | } 36 | swap(arr, moreL, N - 1); 37 | } 38 | 39 | public static void swap(int[] arr, int i, int j) { 40 | int tmp = arr[i]; 41 | arr[i] = arr[j]; 42 | arr[j] = tmp; 43 | } 44 | 45 | // arr[L...R]范围上,拿arr[R]做划分值, 46 | // L....R < = > 47 | public static int[] partition(int[] arr, int L, int R) { 48 | int lessR = L - 1; 49 | int moreL = R; 50 | int index = L; 51 | while (index < moreL) { 52 | if (arr[index] < arr[R]) { 53 | swap(arr, ++lessR, index++); 54 | } else if (arr[index] > arr[R]) { 55 | swap(arr, --moreL, index); 56 | } else { 57 | index++; 58 | } 59 | } 60 | swap(arr, moreL, R); 61 | return new int[] { lessR + 1, moreL }; 62 | } 63 | 64 | public static void quickSort1(int[] arr) { 65 | if (arr == null || arr.length < 2) { 66 | return; 67 | } 68 | process(arr, 0, arr.length - 1); 69 | } 70 | 71 | public static void process(int[] arr, int L, int R) { 72 | if (L >= R) { 73 | return; 74 | } 75 | int[] equalE = partition(arr, L, R); 76 | process(arr, L, equalE[0] - 1); 77 | process(arr, equalE[1] + 1, R); 78 | } 79 | 80 | public static class Job { 81 | public int L; 82 | public int R; 83 | 84 | public Job(int left, int right) { 85 | L = left; 86 | R = right; 87 | } 88 | } 89 | 90 | public static void quickSort2(int[] arr) { 91 | if (arr == null || arr.length < 2) { 92 | return; 93 | } 94 | Stack stack = new Stack<>(); 95 | stack.push(new Job(0, arr.length - 1)); 96 | while (!stack.isEmpty()) { 97 | Job cur = stack.pop(); 98 | int[] equals = partition(arr, cur.L, cur.R); 99 | if (equals[0] > cur.L) { // 有< 区域 100 | stack.push(new Job(cur.L, equals[0] - 1)); 101 | } 102 | if (equals[1] < cur.R) { // 有 > 区域 103 | stack.push(new Job(equals[1] + 1, cur.R)); 104 | } 105 | } 106 | } 107 | 108 | public static int[] netherlandsFlag(int[] arr, int L, int R) { 109 | if (L > R) { 110 | return new int[] { -1, -1 }; 111 | } 112 | if (L == R) { 113 | return new int[] { L, R }; 114 | } 115 | int less = L - 1; 116 | int more = R; 117 | int index = L; 118 | while (index < more) { 119 | if (arr[index] == arr[R]) { 120 | index++; 121 | } else if (arr[index] < arr[R]) { 122 | swap(arr, index++, ++less); 123 | } else { 124 | swap(arr, index, --more); 125 | } 126 | } 127 | swap(arr, more, R); // <[R] =[R] >[R] 128 | return new int[] { less + 1, more }; 129 | } 130 | 131 | public static void quickSort3(int[] arr) { 132 | if (arr == null || arr.length < 2) { 133 | return; 134 | } 135 | process3(arr, 0, arr.length - 1); 136 | } 137 | 138 | public static void process3(int[] arr, int L, int R) { 139 | if (L >= R) { 140 | return; 141 | } 142 | swap(arr, L + (int) (Math.random() * (R - L + 1)), R); 143 | int[] equalArea = netherlandsFlag(arr, L, R); 144 | process3(arr, L, equalArea[0] - 1); 145 | process3(arr, equalArea[1] + 1, R); 146 | } 147 | 148 | // for test 149 | public static int[] generateRandomArray(int maxSize, int maxValue) { 150 | int[] arr = new int[(int) ((maxSize + 1) * Math.random())]; 151 | for (int i = 0; i < arr.length; i++) { 152 | arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random()); 153 | } 154 | return arr; 155 | } 156 | 157 | // for test 158 | public static int[] copyArray(int[] arr) { 159 | if (arr == null) { 160 | return null; 161 | } 162 | int[] res = new int[arr.length]; 163 | for (int i = 0; i < arr.length; i++) { 164 | res[i] = arr[i]; 165 | } 166 | return res; 167 | } 168 | 169 | // for test 170 | public static boolean isEqual(int[] arr1, int[] arr2) { 171 | if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) { 172 | return false; 173 | } 174 | if (arr1 == null && arr2 == null) { 175 | return true; 176 | } 177 | if (arr1.length != arr2.length) { 178 | return false; 179 | } 180 | for (int i = 0; i < arr1.length; i++) { 181 | if (arr1[i] != arr2[i]) { 182 | return false; 183 | } 184 | } 185 | return true; 186 | } 187 | 188 | // for test 189 | public static void printArray(int[] arr) { 190 | if (arr == null) { 191 | return; 192 | } 193 | for (int i = 0; i < arr.length; i++) { 194 | System.out.print(arr[i] + " "); 195 | } 196 | System.out.println(); 197 | } 198 | 199 | // for test 200 | public static void main(String[] args) { 201 | // int[] arr = { 7, 1, 3, 5, 4, 5, 1, 4, 2, 4, 2, 4 }; 202 | // 203 | // splitNum2(arr); 204 | // for (int i = 0; i < arr.length; i++) { 205 | // System.out.print(arr[i] + " "); 206 | // } 207 | 208 | int testTime = 500000; 209 | int maxSize = 100; 210 | int maxValue = 100; 211 | boolean succeed = true; 212 | System.out.println("test begin"); 213 | for (int i = 0; i < testTime; i++) { 214 | int[] arr1 = generateRandomArray(maxSize, maxValue); 215 | int[] arr2 = copyArray(arr1); 216 | int[] arr3 = copyArray(arr1); 217 | quickSort1(arr1); 218 | quickSort2(arr2); 219 | quickSort3(arr3); 220 | if (!isEqual(arr1, arr2) || !isEqual(arr1, arr3)) { 221 | System.out.println("Oops!"); 222 | succeed = false; 223 | break; 224 | } 225 | } 226 | System.out.println("test end"); 227 | System.out.println(succeed ? "Nice!" : "Oops!"); 228 | 229 | } 230 | 231 | } 232 | --------------------------------------------------------------------------------