├── src ├── fy.jpg └── qrcode.png ├── 07-Set-and-Map ├── 02-LinkedListSet │ └── src │ │ ├── Main.java │ │ ├── Set.java │ │ └── BSTSet.java ├── 01-Set-Basics-and-BSTSet │ └── src │ │ ├── Set.java │ │ ├── BSTSet.java │ │ └── Main.java ├── 03-Time-Complexity-of-Set │ └── src │ │ ├── Set.java │ │ ├── Main.java │ │ └── BSTSet.java ├── 07-BSTMap │ └── src │ │ └── Map.java ├── 05-Map-Basics │ └── src │ │ └── Map.java ├── 06-LinkedListMap │ └── src │ │ └── Map.java ├── 08-More-about-Map │ └── src │ │ ├── Map.java │ │ └── Main.java ├── 04-TreeSet-and-Set-Problems-in-Leetcode │ └── src │ │ └── Solution.java └── 09-Leetcode-Problems-about-Map-and-Set │ └── src │ ├── Solution349.java │ └── Solution350.java ├── 09-Segment-Tree ├── 03-Building-Segment-Tree │ └── src │ │ ├── Merger.java │ │ └── Main.java ├── 04-Query-in-Segment-Tree │ └── src │ │ ├── Merger.java │ │ └── Main.java ├── 05-Segment-Tree-Problems-in-Leetcode │ └── src │ │ ├── Merger.java │ │ ├── Main.java │ │ ├── NumArray2.java │ │ ├── NumArray.java │ │ └── NumArray3.java ├── 06-Update-Single-Element-in-Segment-Tree │ └── src │ │ ├── Merger.java │ │ ├── Main.java │ │ └── NumArray.java └── 02-Segment-Tree-Basics │ └── src │ ├── Main.java │ └── SegmentTree.java ├── 02-Arrays ├── 02-Create-Our-Own-Array │ └── src │ │ ├── Main.java │ │ └── Array.java ├── 03-Add-Element-in-Array │ └── src │ │ ├── Main.java │ │ └── Array.java ├── 04-Query-and-Update-Element │ └── src │ │ └── Main.java ├── 01-Array-Basics │ └── src │ │ └── Main.java ├── 07-Dynamic-Array │ └── src │ │ └── Main.java ├── 05-Contain-Find-and-Remove │ └── src │ │ └── Main.java ├── 06-Generic-Data-Structures │ └── src │ │ ├── Main.java │ │ └── Student.java └── 09-Amortized-Time-Complexity │ └── src │ └── Main.java ├── 04-Linked-List ├── 03-DummyHead-in-LinkedList │ └── src │ │ ├── Main.java │ │ └── LinkedList.java ├── 01-Linked-List-Basics │ └── src │ │ ├── Main.java │ │ └── LinkedList.java ├── 02-Add-Elements-in-LinkedList │ └── src │ │ └── Main.java ├── 06-Implement-Stack-in-LinkedList │ └── src │ │ ├── Stack.java │ │ ├── Main.java │ │ ├── LinkedListStack.java │ │ └── ArrayStack.java ├── 07-Implement-Queue-in-LinkedList │ └── src │ │ ├── Queue.java │ │ ├── Main.java │ │ └── ArrayQueue.java ├── 04-Query-and-Update-in-LinkedList │ └── src │ │ └── Main.java └── 05-Remove-Element-in-LinkedList │ └── src │ └── Main.java ├── 10-Trie ├── 02-Trie-Basics │ └── src │ │ ├── Main.java │ │ └── Trie.java ├── 03-Searching-in-Trie │ └── src │ │ ├── Set.java │ │ ├── BSTSet.java │ │ ├── Main.java │ │ └── Trie.java ├── 04-Prefix-in-Trie │ └── src │ │ ├── Set.java │ │ ├── BSTSet.java │ │ ├── Main.java │ │ └── Trie208.java ├── 08-Trie-Using-HashMap-and-Array │ └── src │ │ ├── Set.java │ │ ├── BSTSet.java │ │ ├── Trie3.java │ │ ├── Trie.java │ │ └── Trie2.java └── 06-Trie-and-Map │ └── src │ └── MapSum.java ├── 03-Stacks-and-Queues ├── 06-Loop-Queue │ └── src │ │ ├── Main.java │ │ ├── Queue.java │ │ ├── LoopQueue.java │ │ └── ArrayQueue.java ├── 07-Implementation-of-Loop-Queue │ └── src │ │ ├── Main.java │ │ ├── Queue.java │ │ └── ArrayQueue.java ├── 02-Array-Stack │ └── src │ │ ├── Stack.java │ │ ├── Main.java │ │ └── ArrayStack.java ├── 04-More-about-Leetcode │ └── src │ │ ├── Stack.java │ │ ├── Solution.java │ │ └── ArrayStack.java ├── 05-Array-Queue │ └── src │ │ ├── Queue.java │ │ └── ArrayQueue.java ├── 08-Queues-Comparison │ └── src │ │ ├── Queue.java │ │ ├── Main.java │ │ └── ArrayQueue.java ├── Optional-02-Loop-Queue-without-Size-Member │ └── src │ │ └── Queue.java ├── Optional-01-Loop-Queue-without-Wasting-One-Space │ └── src │ │ └── Queue.java └── 03-A-Stack-Problem-in-Leetcode │ └── src │ └── Solution.java ├── 12-AVL-Tree ├── 04-Rotation-Operations │ └── src │ │ └── Main.java ├── 02-Calculating-Balance-Factor │ └── src │ │ └── Main.java ├── 03-Checking-Balancing-and-Binary-Search-Property │ └── src │ │ └── Main.java ├── 05-The-Implementation-of-Left-Rotation-and-Right-Rotation │ └── src │ │ └── Main.java ├── 08-Map-and-Set-in-AVL-Tree │ └── src │ │ ├── Set.java │ │ ├── Map.java │ │ ├── AVLSet.java │ │ ├── AVLMap.java │ │ ├── TestSetMain.java │ │ ├── BSTSet.java │ │ └── TestMapMain.java ├── 07-Remove-Elements-in-AVL-Tree │ └── src │ │ └── Main.java └── 06-LR-and-RL │ └── src │ └── Main.java ├── 08-Heap-and-Priority-Queue ├── 02-Heap-Basics │ └── src │ │ ├── Main.java │ │ └── MaxHeap.java ├── 03-Add-and-Sift-Up-in-Heap │ └── src │ │ ├── Main.java │ │ └── MaxHeap.java ├── 06-Priority-Queue │ └── src │ │ ├── Queue.java │ │ ├── PriorityQueue.java │ │ └── Main.java ├── 04-Extract-and-Sift-Down-in-Heap │ └── src │ │ └── Main.java ├── 08-Priority-Queue-in-Java │ └── src │ │ ├── Solution5.java │ │ ├── Solution4.java │ │ ├── Solution3.java │ │ └── Solution2.java └── 05-Heapify-and-Replace-in-Heap │ └── src │ └── Main.java ├── 11-Union-Find ├── 03-Quick-Union │ └── src │ │ ├── Main.java │ │ ├── UF.java │ │ ├── UnionFind1.java │ │ └── UnionFind2.java ├── 01-What-is-UnionFind │ └── src │ │ └── UF.java ├── 02-Quick-Find │ └── src │ │ ├── UF.java │ │ └── UnionFind1.java ├── 04-Optimized-by-Size │ └── src │ │ ├── UF.java │ │ ├── UnionFind1.java │ │ ├── UnionFind2.java │ │ ├── Main.java │ │ └── UnionFind3.java ├── 05-Optimized-by-Rank │ └── src │ │ ├── UF.java │ │ ├── UnionFind1.java │ │ ├── UnionFind2.java │ │ ├── Main.java │ │ ├── UnionFind3.java │ │ └── UnionFind4.java ├── 06-Path-Compression │ └── src │ │ ├── UF.java │ │ ├── UnionFind1.java │ │ ├── UnionFind2.java │ │ ├── Main.java │ │ ├── UnionFind3.java │ │ └── UnionFind4.java └── 07-More-about-Union-Find │ └── src │ ├── UF.java │ ├── UnionFind1.java │ ├── UnionFind2.java │ ├── Main.java │ ├── UnionFind3.java │ └── UnionFind4.java ├── 06-Binary-Search-Tree ├── Optional-05-Binary-Tree-Morris-Traversal │ └── src │ │ ├── TreeNode.java │ │ ├── PreorderSolution.java │ │ └── InorderSolution.java ├── Optional-03-Binary-Tree-Classic-Nonrecursive-Traversal │ ├── Inorder │ │ └── src │ │ │ ├── TreeNode.java │ │ │ ├── Solution1.java │ │ │ └── Solution2.java │ ├── Postorder │ │ └── src │ │ │ ├── TreeNode.java │ │ │ ├── Solution2.java │ │ │ ├── Solution3.java │ │ │ ├── Solution5.java │ │ │ ├── Solution6.java │ │ │ ├── Solution4.java │ │ │ └── Solution1.java │ └── Preorder │ │ └── src │ │ ├── TreeNode.java │ │ ├── Solution2.java │ │ ├── Solution1.java │ │ └── Solution3.java ├── 06-PreOrder-Traverse-in-BST │ └── src │ │ └── Main.java ├── 02-Binary-Search-Tree-Basics │ └── src │ │ └── BST.java ├── 09-Non-Recursion-Preorder-Traverse-in-BST │ └── src │ │ ├── Main.java │ │ └── Solution.java ├── 07-InOrder-and-PostOrder-Traverse-in-BST │ └── src │ │ └── Main.java ├── 10-Level-Traverse-in-BST │ └── src │ │ └── Main.java ├── 04-Improved-Add-Elements-in-BST │ └── src │ │ └── BST.java ├── 12-Remove-Elements-in-BST │ └── src │ │ └── Main.java ├── 11-Remove-Min-and-Max-in-BST │ └── src │ │ └── Main.java ├── 03-Add-Elements-in-BST │ └── src │ │ └── BST.java └── 05-Search-in-BST │ └── src │ └── BST.java ├── 05-Recursion ├── 01-Linked-List-Problems-in-Leetcode │ └── src │ │ ├── ListNode.java │ │ ├── Solution3.java │ │ ├── Solution2.java │ │ └── Solution.java ├── 03-Recursion-Basics │ └── src │ │ ├── Sum.java │ │ ├── Solution3.java │ │ ├── Solution2.java │ │ ├── ListNode.java │ │ └── Solution.java ├── 04-LinkedList-and-Recursion │ └── src │ │ ├── Sum.java │ │ ├── Solution5.java │ │ ├── Solution4.java │ │ ├── Solution3.java │ │ ├── Solution2.java │ │ ├── ListNode.java │ │ └── Solution.java ├── 02-Test-Your-LinkedList-Solution │ └── src │ │ ├── Solution3.java │ │ ├── Solution2.java │ │ ├── ListNode.java │ │ └── Solution.java └── 06-Debug-Recursive-Solution │ └── src │ ├── ListNode.java │ └── Solution.java ├── 14-Hash-Table ├── 01-Hash-Table-Basics │ └── src │ │ └── Solution.java ├── 03-Hash-Function-in-Java │ └── src │ │ ├── Main.java │ │ └── Student.java └── 05-Hash-Table-Implementation │ └── src │ └── HashTable.java ├── .gitignore └── 13-Red-Black-Tree ├── 08-The-Performance-of-Red-Black-Tree └── src │ ├── Main3.java │ └── Main2.java ├── 05-Keep-Root-Black-and-Left-Rotation └── src │ └── Main.java ├── 06-Flip-Colors-and-Right-Rotation └── src │ └── Main.java ├── 07-Adding-Elements-in-Red-Black-Tree └── src │ └── Main.java └── 03-The-Equivalence-of-RBTree-and-2-3-Tree └── src └── Main.java /src/fy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liuyubobobo/Play-with-Data-Structures/HEAD/src/fy.jpg -------------------------------------------------------------------------------- /src/qrcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liuyubobobo/Play-with-Data-Structures/HEAD/src/qrcode.png -------------------------------------------------------------------------------- /07-Set-and-Map/02-LinkedListSet/src/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class Main { 4 | 5 | 6 | } 7 | -------------------------------------------------------------------------------- /09-Segment-Tree/03-Building-Segment-Tree/src/Merger.java: -------------------------------------------------------------------------------- 1 | public interface Merger { 2 | E merge(E a, E b); 3 | } 4 | -------------------------------------------------------------------------------- /09-Segment-Tree/04-Query-in-Segment-Tree/src/Merger.java: -------------------------------------------------------------------------------- 1 | public interface Merger { 2 | E merge(E a, E b); 3 | } 4 | -------------------------------------------------------------------------------- /09-Segment-Tree/05-Segment-Tree-Problems-in-Leetcode/src/Merger.java: -------------------------------------------------------------------------------- 1 | public interface Merger { 2 | E merge(E a, E b); 3 | } 4 | -------------------------------------------------------------------------------- /09-Segment-Tree/06-Update-Single-Element-in-Segment-Tree/src/Merger.java: -------------------------------------------------------------------------------- 1 | public interface Merger { 2 | E merge(E a, E b); 3 | } 4 | -------------------------------------------------------------------------------- /02-Arrays/02-Create-Our-Own-Array/src/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static void main(String[] args) { 4 | 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /02-Arrays/03-Add-Element-in-Array/src/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static void main(String[] args) { 4 | 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /04-Linked-List/03-DummyHead-in-LinkedList/src/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static void main(String[] args) { 4 | 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /10-Trie/02-Trie-Basics/src/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static void main(String[] args) { 4 | // write your code here 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /03-Stacks-and-Queues/06-Loop-Queue/src/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static void main(String[] args) { 4 | // write your code here 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /04-Linked-List/01-Linked-List-Basics/src/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static void main(String[] args) { 4 | // write your code here 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /12-AVL-Tree/04-Rotation-Operations/src/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static void main(String[] args) { 4 | // write your code here 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /08-Heap-and-Priority-Queue/02-Heap-Basics/src/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static void main(String[] args) { 4 | // write your code here 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /09-Segment-Tree/02-Segment-Tree-Basics/src/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static void main(String[] args) { 4 | // write your code here 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /11-Union-Find/03-Quick-Union/src/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.Random; 2 | 3 | public class Main { 4 | 5 | public static void main(String[] args) { 6 | 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /12-AVL-Tree/02-Calculating-Balance-Factor/src/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static void main(String[] args) { 4 | // write your code here 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /04-Linked-List/02-Add-Elements-in-LinkedList/src/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static void main(String[] args) { 4 | // write your code here 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /11-Union-Find/01-What-is-UnionFind/src/UF.java: -------------------------------------------------------------------------------- 1 | public interface UF { 2 | 3 | int getSize(); 4 | boolean isConnected(int p, int q); 5 | void unionElements(int p, int q); 6 | } -------------------------------------------------------------------------------- /11-Union-Find/02-Quick-Find/src/UF.java: -------------------------------------------------------------------------------- 1 | public interface UF { 2 | 3 | int getSize(); 4 | boolean isConnected(int p, int q); 5 | void unionElements(int p, int q); 6 | } 7 | -------------------------------------------------------------------------------- /11-Union-Find/03-Quick-Union/src/UF.java: -------------------------------------------------------------------------------- 1 | public interface UF { 2 | 3 | int getSize(); 4 | boolean isConnected(int p, int q); 5 | void unionElements(int p, int q); 6 | } 7 | -------------------------------------------------------------------------------- /03-Stacks-and-Queues/07-Implementation-of-Loop-Queue/src/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static void main(String[] args) { 4 | // write your code here 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /08-Heap-and-Priority-Queue/03-Add-and-Sift-Up-in-Heap/src/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static void main(String[] args) { 4 | // write your code here 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /11-Union-Find/04-Optimized-by-Size/src/UF.java: -------------------------------------------------------------------------------- 1 | public interface UF { 2 | 3 | int getSize(); 4 | boolean isConnected(int p, int q); 5 | void unionElements(int p, int q); 6 | } 7 | -------------------------------------------------------------------------------- /11-Union-Find/05-Optimized-by-Rank/src/UF.java: -------------------------------------------------------------------------------- 1 | public interface UF { 2 | 3 | int getSize(); 4 | boolean isConnected(int p, int q); 5 | void unionElements(int p, int q); 6 | } 7 | -------------------------------------------------------------------------------- /11-Union-Find/06-Path-Compression/src/UF.java: -------------------------------------------------------------------------------- 1 | public interface UF { 2 | 3 | int getSize(); 4 | boolean isConnected(int p, int q); 5 | void unionElements(int p, int q); 6 | } 7 | -------------------------------------------------------------------------------- /11-Union-Find/07-More-about-Union-Find/src/UF.java: -------------------------------------------------------------------------------- 1 | public interface UF { 2 | 3 | int getSize(); 4 | boolean isConnected(int p, int q); 5 | void unionElements(int p, int q); 6 | } 7 | -------------------------------------------------------------------------------- /12-AVL-Tree/03-Checking-Balancing-and-Binary-Search-Property/src/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static void main(String[] args) { 4 | // write your code here 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /03-Stacks-and-Queues/02-Array-Stack/src/Stack.java: -------------------------------------------------------------------------------- 1 | public interface Stack { 2 | 3 | int getSize(); 4 | boolean isEmpty(); 5 | void push(E e); 6 | E pop(); 7 | E peek(); 8 | } 9 | -------------------------------------------------------------------------------- /12-AVL-Tree/05-The-Implementation-of-Left-Rotation-and-Right-Rotation/src/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static void main(String[] args) { 4 | // write your code here 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /03-Stacks-and-Queues/04-More-about-Leetcode/src/Stack.java: -------------------------------------------------------------------------------- 1 | public interface Stack { 2 | 3 | int getSize(); 4 | boolean isEmpty(); 5 | void push(E e); 6 | E pop(); 7 | E peek(); 8 | } 9 | -------------------------------------------------------------------------------- /03-Stacks-and-Queues/05-Array-Queue/src/Queue.java: -------------------------------------------------------------------------------- 1 | public interface Queue { 2 | 3 | int getSize(); 4 | boolean isEmpty(); 5 | void enqueue(E e); 6 | E dequeue(); 7 | E getFront(); 8 | } 9 | -------------------------------------------------------------------------------- /03-Stacks-and-Queues/06-Loop-Queue/src/Queue.java: -------------------------------------------------------------------------------- 1 | public interface Queue { 2 | 3 | int getSize(); 4 | boolean isEmpty(); 5 | void enqueue(E e); 6 | E dequeue(); 7 | E getFront(); 8 | } 9 | -------------------------------------------------------------------------------- /10-Trie/03-Searching-in-Trie/src/Set.java: -------------------------------------------------------------------------------- 1 | public interface Set { 2 | 3 | void add(E e); 4 | boolean contains(E e); 5 | void remove(E e); 6 | int getSize(); 7 | boolean isEmpty(); 8 | } 9 | -------------------------------------------------------------------------------- /10-Trie/04-Prefix-in-Trie/src/Set.java: -------------------------------------------------------------------------------- 1 | public interface Set { 2 | 3 | void add(E e); 4 | boolean contains(E e); 5 | void remove(E e); 6 | int getSize(); 7 | boolean isEmpty(); 8 | } 9 | -------------------------------------------------------------------------------- /04-Linked-List/06-Implement-Stack-in-LinkedList/src/Stack.java: -------------------------------------------------------------------------------- 1 | public interface Stack { 2 | 3 | int getSize(); 4 | boolean isEmpty(); 5 | void push(E e); 6 | E pop(); 7 | E peek(); 8 | } 9 | -------------------------------------------------------------------------------- /07-Set-and-Map/02-LinkedListSet/src/Set.java: -------------------------------------------------------------------------------- 1 | public interface Set { 2 | 3 | void add(E e); 4 | boolean contains(E e); 5 | void remove(E e); 6 | int getSize(); 7 | boolean isEmpty(); 8 | } 9 | -------------------------------------------------------------------------------- /03-Stacks-and-Queues/08-Queues-Comparison/src/Queue.java: -------------------------------------------------------------------------------- 1 | public interface Queue { 2 | 3 | int getSize(); 4 | boolean isEmpty(); 5 | void enqueue(E e); 6 | E dequeue(); 7 | E getFront(); 8 | } 9 | -------------------------------------------------------------------------------- /07-Set-and-Map/01-Set-Basics-and-BSTSet/src/Set.java: -------------------------------------------------------------------------------- 1 | public interface Set { 2 | 3 | void add(E e); 4 | boolean contains(E e); 5 | void remove(E e); 6 | int getSize(); 7 | boolean isEmpty(); 8 | } 9 | -------------------------------------------------------------------------------- /08-Heap-and-Priority-Queue/06-Priority-Queue/src/Queue.java: -------------------------------------------------------------------------------- 1 | public interface Queue { 2 | 3 | int getSize(); 4 | boolean isEmpty(); 5 | void enqueue(E e); 6 | E dequeue(); 7 | E getFront(); 8 | } 9 | -------------------------------------------------------------------------------- /10-Trie/08-Trie-Using-HashMap-and-Array/src/Set.java: -------------------------------------------------------------------------------- 1 | public interface Set { 2 | 3 | void add(E e); 4 | boolean contains(E e); 5 | void remove(E e); 6 | int getSize(); 7 | boolean isEmpty(); 8 | } 9 | -------------------------------------------------------------------------------- /12-AVL-Tree/08-Map-and-Set-in-AVL-Tree/src/Set.java: -------------------------------------------------------------------------------- 1 | public interface Set { 2 | 3 | void add(E e); 4 | boolean contains(E e); 5 | void remove(E e); 6 | int getSize(); 7 | boolean isEmpty(); 8 | } 9 | -------------------------------------------------------------------------------- /04-Linked-List/07-Implement-Queue-in-LinkedList/src/Queue.java: -------------------------------------------------------------------------------- 1 | public interface Queue { 2 | 3 | int getSize(); 4 | boolean isEmpty(); 5 | void enqueue(E e); 6 | E dequeue(); 7 | E getFront(); 8 | } 9 | -------------------------------------------------------------------------------- /07-Set-and-Map/03-Time-Complexity-of-Set/src/Set.java: -------------------------------------------------------------------------------- 1 | public interface Set { 2 | 3 | void add(E e); 4 | boolean contains(E e); 5 | void remove(E e); 6 | int getSize(); 7 | boolean isEmpty(); 8 | } 9 | -------------------------------------------------------------------------------- /03-Stacks-and-Queues/07-Implementation-of-Loop-Queue/src/Queue.java: -------------------------------------------------------------------------------- 1 | public interface Queue { 2 | 3 | int getSize(); 4 | boolean isEmpty(); 5 | void enqueue(E e); 6 | E dequeue(); 7 | E getFront(); 8 | } 9 | -------------------------------------------------------------------------------- /03-Stacks-and-Queues/Optional-02-Loop-Queue-without-Size-Member/src/Queue.java: -------------------------------------------------------------------------------- 1 | public interface Queue { 2 | 3 | int getSize(); 4 | boolean isEmpty(); 5 | void enqueue(E e); 6 | E dequeue(); 7 | E getFront(); 8 | } 9 | -------------------------------------------------------------------------------- /03-Stacks-and-Queues/Optional-01-Loop-Queue-without-Wasting-One-Space/src/Queue.java: -------------------------------------------------------------------------------- 1 | public interface Queue { 2 | 3 | int getSize(); 4 | boolean isEmpty(); 5 | void enqueue(E e); 6 | E dequeue(); 7 | E getFront(); 8 | } 9 | -------------------------------------------------------------------------------- /06-Binary-Search-Tree/Optional-05-Binary-Tree-Morris-Traversal/src/TreeNode.java: -------------------------------------------------------------------------------- 1 | // Definition for a binary tree node. 2 | public class TreeNode { 3 | int val; 4 | TreeNode left; 5 | TreeNode right; 6 | TreeNode(int x) { val = x; } 7 | } -------------------------------------------------------------------------------- /05-Recursion/01-Linked-List-Problems-in-Leetcode/src/ListNode.java: -------------------------------------------------------------------------------- 1 | //Definition for singly-linked list. 2 | public class ListNode { 3 | 4 | public int val; 5 | public ListNode next; 6 | 7 | public ListNode(int x) { 8 | val = x; 9 | } 10 | } -------------------------------------------------------------------------------- /06-Binary-Search-Tree/Optional-03-Binary-Tree-Classic-Nonrecursive-Traversal/Inorder/src/TreeNode.java: -------------------------------------------------------------------------------- 1 | // Definition for a binary tree node. 2 | public class TreeNode { 3 | int val; 4 | TreeNode left; 5 | TreeNode right; 6 | TreeNode(int x) { val = x; } 7 | } -------------------------------------------------------------------------------- /06-Binary-Search-Tree/Optional-03-Binary-Tree-Classic-Nonrecursive-Traversal/Postorder/src/TreeNode.java: -------------------------------------------------------------------------------- 1 | // Definition for a binary tree node. 2 | public class TreeNode { 3 | int val; 4 | TreeNode left; 5 | TreeNode right; 6 | TreeNode(int x) { val = x; } 7 | } -------------------------------------------------------------------------------- /06-Binary-Search-Tree/Optional-03-Binary-Tree-Classic-Nonrecursive-Traversal/Preorder/src/TreeNode.java: -------------------------------------------------------------------------------- 1 | // Definition for a binary tree node. 2 | public class TreeNode { 3 | int val; 4 | TreeNode left; 5 | TreeNode right; 6 | TreeNode(int x) { val = x; } 7 | } -------------------------------------------------------------------------------- /07-Set-and-Map/07-BSTMap/src/Map.java: -------------------------------------------------------------------------------- 1 | public interface Map { 2 | 3 | void add(K key, V value); 4 | boolean contains(K key); 5 | V get(K key); 6 | void set(K key, V value); 7 | V remove(K key); 8 | int getSize(); 9 | boolean isEmpty(); 10 | } 11 | -------------------------------------------------------------------------------- /07-Set-and-Map/05-Map-Basics/src/Map.java: -------------------------------------------------------------------------------- 1 | public interface Map { 2 | 3 | void add(K key, V value); 4 | V remove(K key); 5 | boolean contains(K key); 6 | V get(K key); 7 | void set(K key, V newValue); 8 | int getSize(); 9 | boolean isEmpty(); 10 | } 11 | -------------------------------------------------------------------------------- /07-Set-and-Map/06-LinkedListMap/src/Map.java: -------------------------------------------------------------------------------- 1 | public interface Map { 2 | 3 | void add(K key, V value); 4 | V remove(K key); 5 | boolean contains(K key); 6 | V get(K key); 7 | void set(K key, V newValue); 8 | int getSize(); 9 | boolean isEmpty(); 10 | } 11 | -------------------------------------------------------------------------------- /07-Set-and-Map/08-More-about-Map/src/Map.java: -------------------------------------------------------------------------------- 1 | public interface Map { 2 | 3 | void add(K key, V value); 4 | boolean contains(K key); 5 | V get(K key); 6 | void set(K key, V newValue); 7 | V remove(K key); 8 | int getSize(); 9 | boolean isEmpty(); 10 | } 11 | -------------------------------------------------------------------------------- /12-AVL-Tree/08-Map-and-Set-in-AVL-Tree/src/Map.java: -------------------------------------------------------------------------------- 1 | public interface Map { 2 | 3 | void add(K key, V value); 4 | boolean contains(K key); 5 | V get(K key); 6 | void set(K key, V newValue); 7 | V remove(K key); 8 | int getSize(); 9 | boolean isEmpty(); 10 | } 11 | -------------------------------------------------------------------------------- /03-Stacks-and-Queues/02-Array-Stack/src/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static void main(String[] args) { 4 | 5 | ArrayStack stack = new ArrayStack<>(); 6 | 7 | for(int i = 0 ; i < 5 ; i ++){ 8 | stack.push(i); 9 | System.out.println(stack); 10 | } 11 | 12 | stack.pop(); 13 | System.out.println(stack); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /14-Hash-Table/01-Hash-Table-Basics/src/Solution.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int firstUniqChar(String s) { 3 | 4 | int[] freq = new int[26]; 5 | for(int i = 0 ; i < s.length() ; i ++) 6 | freq[s.charAt(i) - 'a'] ++; 7 | 8 | for(int i = 0 ; i < s.length() ; i ++) 9 | if(freq[s.charAt(i) - 'a'] == 1) 10 | return i; 11 | 12 | return -1; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /02-Arrays/04-Query-and-Update-Element/src/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static void main(String[] args) { 4 | 5 | Array arr = new Array(20); 6 | for(int i = 0 ; i < 10 ; i ++) 7 | arr.addLast(i); 8 | System.out.println(arr); 9 | 10 | arr.add(1, 100); 11 | System.out.println(arr); 12 | 13 | arr.addFirst(-1); 14 | System.out.println(arr); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /04-Linked-List/04-Query-and-Update-in-LinkedList/src/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static void main(String[] args) { 4 | 5 | LinkedList linkedList = new LinkedList<>(); 6 | for(int i = 0 ; i < 5 ; i ++){ 7 | linkedList.addFirst(i); 8 | System.out.println(linkedList); 9 | } 10 | 11 | linkedList.add(2, 666); 12 | System.out.println(linkedList); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /05-Recursion/03-Recursion-Basics/src/Sum.java: -------------------------------------------------------------------------------- 1 | public class Sum { 2 | 3 | public static int sum(int[] arr){ 4 | return sum(arr, 0); 5 | } 6 | 7 | // 计算arr[l...n)这个区间内所有数字的和 8 | private static int sum(int[] arr, int l){ 9 | if(l == arr.length) 10 | return 0; 11 | return arr[l] + sum(arr, l + 1); 12 | } 13 | 14 | public static void main(String[] args) { 15 | 16 | int[] nums = {1, 2, 3, 4, 5, 6, 7, 8}; 17 | System.out.println(sum(nums)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /05-Recursion/04-LinkedList-and-Recursion/src/Sum.java: -------------------------------------------------------------------------------- 1 | public class Sum { 2 | 3 | public static int sum(int[] arr){ 4 | return sum(arr, 0); 5 | } 6 | 7 | // 计算arr[l...n)这个区间内所有数字的和 8 | private static int sum(int[] arr, int l){ 9 | if(l == arr.length) 10 | return 0; 11 | return arr[l] + sum(arr, l + 1); 12 | } 13 | 14 | public static void main(String[] args) { 15 | 16 | int[] nums = {1, 2, 3, 4, 5, 6, 7, 8}; 17 | System.out.println(sum(nums)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /04-Linked-List/01-Linked-List-Basics/src/LinkedList.java: -------------------------------------------------------------------------------- 1 | public class LinkedList { 2 | 3 | private class Node{ 4 | public E e; 5 | public Node next; 6 | 7 | public Node(E e, Node next){ 8 | this.e = e; 9 | this.next = next; 10 | } 11 | 12 | public Node(E e){ 13 | this(e, null); 14 | } 15 | 16 | public Node(){ 17 | this(null, null); 18 | } 19 | 20 | @Override 21 | public String toString(){ 22 | return e.toString(); 23 | } 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /02-Arrays/01-Array-Basics/src/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static void main(String[] args) { 4 | 5 | int[] arr = new int[10]; 6 | for(int i = 0 ; i < arr.length ; i ++) 7 | arr[i] = i; 8 | 9 | int[] scores = new int[]{100, 99, 66}; 10 | for(int i = 0 ; i < scores.length ; i ++) 11 | System.out.println(scores[i]); 12 | 13 | for(int score: scores) 14 | System.out.println(score); 15 | 16 | scores[0] = 96; 17 | 18 | for(int i = 0 ; i < scores.length ; i ++) 19 | System.out.println(scores[i]); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /06-Binary-Search-Tree/06-PreOrder-Traverse-in-BST/src/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static void main(String[] args) { 4 | 5 | BST bst = new BST<>(); 6 | int[] nums = {5, 3, 6, 8, 4, 2}; 7 | for(int num: nums) 8 | bst.add(num); 9 | 10 | ///////////////// 11 | // 5 // 12 | // / \ // 13 | // 3 6 // 14 | // / \ \ // 15 | // 2 4 8 // 16 | ///////////////// 17 | bst.preOrder(); 18 | System.out.println(); 19 | 20 | System.out.println(bst); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /09-Segment-Tree/04-Query-in-Segment-Tree/src/Main.java: -------------------------------------------------------------------------------- 1 | /// 该测试用例来源:Leetcode 303. Range Sum Query - Immutable 2 | /// https://leetcode.com/problems/range-sum-query-immutable/description/ 3 | public class Main { 4 | 5 | public static void main(String[] args) { 6 | 7 | Integer[] nums = {-2, 0, 3, -5, 2, -1}; 8 | 9 | SegmentTree segTree = new SegmentTree<>(nums, 10 | (a, b) -> a + b); 11 | System.out.println(segTree); 12 | 13 | System.out.println(segTree.query(0, 2)); 14 | System.out.println(segTree.query(2, 5)); 15 | System.out.println(segTree.query(0, 5)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /06-Binary-Search-Tree/02-Binary-Search-Tree-Basics/src/BST.java: -------------------------------------------------------------------------------- 1 | public class BST> { 2 | 3 | private class Node { 4 | public E e; 5 | public Node left, right; 6 | 7 | public Node(E e) { 8 | this.e = e; 9 | left = null; 10 | right = null; 11 | } 12 | } 13 | 14 | private Node root; 15 | private int size; 16 | 17 | public BST(){ 18 | root = null; 19 | size = 0; 20 | } 21 | 22 | public int size(){ 23 | return size; 24 | } 25 | 26 | public boolean isEmpty(){ 27 | return size == 0; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /02-Arrays/07-Dynamic-Array/src/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static void main(String[] args) { 4 | 5 | Array arr = new Array<>(); 6 | for(int i = 0 ; i < 10 ; i ++) 7 | arr.addLast(i); 8 | System.out.println(arr); 9 | 10 | arr.add(1, 100); 11 | System.out.println(arr); 12 | 13 | arr.addFirst(-1); 14 | System.out.println(arr); 15 | 16 | arr.remove(2); 17 | System.out.println(arr); 18 | 19 | arr.removeElement(4); 20 | System.out.println(arr); 21 | 22 | arr.removeFirst(); 23 | System.out.println(arr); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /09-Segment-Tree/05-Segment-Tree-Problems-in-Leetcode/src/Main.java: -------------------------------------------------------------------------------- 1 | /// 该测试用例来源:Leetcode 303. Range Sum Query - Immutable 2 | /// https://leetcode.com/problems/range-sum-query-immutable/description/ 3 | public class Main { 4 | 5 | public static void main(String[] args) { 6 | 7 | Integer[] nums = {-2, 0, 3, -5, 2, -1}; 8 | 9 | SegmentTree segTree = new SegmentTree<>(nums, 10 | (a, b) -> a + b); 11 | System.out.println(segTree); 12 | 13 | System.out.println(segTree.query(0, 2)); 14 | System.out.println(segTree.query(2, 5)); 15 | System.out.println(segTree.query(0, 5)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /09-Segment-Tree/06-Update-Single-Element-in-Segment-Tree/src/Main.java: -------------------------------------------------------------------------------- 1 | /// 该测试用例来源:Leetcode 303. Range Sum Query - Immutable 2 | /// https://leetcode.com/problems/range-sum-query-immutable/description/ 3 | public class Main { 4 | 5 | public static void main(String[] args) { 6 | 7 | Integer[] nums = {-2, 0, 3, -5, 2, -1}; 8 | 9 | SegmentTree segTree = new SegmentTree<>(nums, 10 | (a, b) -> a + b); 11 | System.out.println(segTree); 12 | 13 | System.out.println(segTree.query(0, 2)); 14 | System.out.println(segTree.query(2, 5)); 15 | System.out.println(segTree.query(0, 5)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /06-Binary-Search-Tree/09-Non-Recursion-Preorder-Traverse-in-BST/src/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static void main(String[] args) { 4 | 5 | BST bst = new BST<>(); 6 | int[] nums = {5, 3, 6, 8, 4, 2}; 7 | for(int num: nums) 8 | bst.add(num); 9 | 10 | ///////////////// 11 | // 5 // 12 | // / \ // 13 | // 3 6 // 14 | // / \ \ // 15 | // 2 4 8 // 16 | ///////////////// 17 | bst.preOrder(); 18 | System.out.println(); 19 | 20 | bst.preOrderNR(); 21 | System.out.println(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /09-Segment-Tree/03-Building-Segment-Tree/src/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static void main(String[] args) { 4 | 5 | Integer[] nums = {-2, 0, 3, -5, 2, -1}; 6 | // SegmentTree segTree = new SegmentTree<>(nums, 7 | // new Merger() { 8 | // @Override 9 | // public Integer merge(Integer a, Integer b) { 10 | // return a + b; 11 | // } 12 | // }); 13 | 14 | SegmentTree segTree = new SegmentTree<>(nums, 15 | (a, b) -> a + b); 16 | System.out.println(segTree); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /05-Recursion/01-Linked-List-Problems-in-Leetcode/src/Solution3.java: -------------------------------------------------------------------------------- 1 | /// Leetcode 203. Remove Linked List Elements 2 | /// https://leetcode.com/problems/remove-linked-list-elements/description/ 3 | 4 | class Solution3 { 5 | 6 | public ListNode removeElements(ListNode head, int val) { 7 | 8 | ListNode dummyHead = new ListNode(-1); 9 | dummyHead.next = head; 10 | 11 | ListNode prev = dummyHead; 12 | while(prev.next != null){ 13 | if(prev.next.val == val) 14 | prev.next = prev.next.next; 15 | else 16 | prev = prev.next; 17 | } 18 | 19 | return dummyHead.next; 20 | } 21 | } -------------------------------------------------------------------------------- /02-Arrays/02-Create-Our-Own-Array/src/Array.java: -------------------------------------------------------------------------------- 1 | public class Array { 2 | 3 | private int[] data; 4 | private int size; 5 | 6 | // 构造函数,传入数组的容量capacity构造Array 7 | public Array(int capacity){ 8 | data = new int[capacity]; 9 | size = 0; 10 | } 11 | 12 | // 无参数的构造函数,默认数组的容量capacity=10 13 | public Array(){ 14 | this(10); 15 | } 16 | 17 | // 获取数组的容量 18 | public int getCapacity(){ 19 | return data.length; 20 | } 21 | 22 | // 获取数组中的元素个数 23 | public int getSize(){ 24 | return size; 25 | } 26 | 27 | // 返回数组是否为空 28 | public boolean isEmpty(){ 29 | return size == 0; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /04-Linked-List/05-Remove-Element-in-LinkedList/src/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static void main(String[] args) { 4 | 5 | LinkedList linkedList = new LinkedList<>(); 6 | for(int i = 0 ; i < 5 ; i ++){ 7 | linkedList.addFirst(i); 8 | System.out.println(linkedList); 9 | } 10 | 11 | linkedList.add(2, 666); 12 | System.out.println(linkedList); 13 | 14 | linkedList.remove(2); 15 | System.out.println(linkedList); 16 | 17 | linkedList.removeFirst(); 18 | System.out.println(linkedList); 19 | 20 | linkedList.removeLast(); 21 | System.out.println(linkedList); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /10-Trie/04-Prefix-in-Trie/src/BSTSet.java: -------------------------------------------------------------------------------- 1 | public class BSTSet> implements Set { 2 | 3 | private BST bst; 4 | 5 | public BSTSet(){ 6 | bst = new BST<>(); 7 | } 8 | 9 | @Override 10 | public int getSize(){ 11 | return bst.size(); 12 | } 13 | 14 | @Override 15 | public boolean isEmpty(){ 16 | return bst.isEmpty(); 17 | } 18 | 19 | @Override 20 | public void add(E e){ 21 | bst.add(e); 22 | } 23 | 24 | @Override 25 | public boolean contains(E e){ 26 | return bst.contains(e); 27 | } 28 | 29 | @Override 30 | public void remove(E e){ 31 | bst.remove(e); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /02-Arrays/05-Contain-Find-and-Remove/src/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static void main(String[] args) { 4 | 5 | Array arr = new Array(20); 6 | for(int i = 0 ; i < 10 ; i ++) 7 | arr.addLast(i); 8 | System.out.println(arr); 9 | 10 | arr.add(1, 100); 11 | System.out.println(arr); 12 | 13 | arr.addFirst(-1); 14 | System.out.println(arr); 15 | // [-1, 0, 100, 1, 2, 3, 4, 5, 6, 7, 8, 9] 16 | 17 | arr.remove(2); 18 | System.out.println(arr); 19 | 20 | arr.removeElement(4); 21 | System.out.println(arr); 22 | 23 | arr.removeFirst(); 24 | System.out.println(arr); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /10-Trie/03-Searching-in-Trie/src/BSTSet.java: -------------------------------------------------------------------------------- 1 | public class BSTSet> implements Set { 2 | 3 | private BST bst; 4 | 5 | public BSTSet(){ 6 | bst = new BST<>(); 7 | } 8 | 9 | @Override 10 | public int getSize(){ 11 | return bst.size(); 12 | } 13 | 14 | @Override 15 | public boolean isEmpty(){ 16 | return bst.isEmpty(); 17 | } 18 | 19 | @Override 20 | public void add(E e){ 21 | bst.add(e); 22 | } 23 | 24 | @Override 25 | public boolean contains(E e){ 26 | return bst.contains(e); 27 | } 28 | 29 | @Override 30 | public void remove(E e){ 31 | bst.remove(e); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /05-Recursion/01-Linked-List-Problems-in-Leetcode/src/Solution2.java: -------------------------------------------------------------------------------- 1 | /// Leetcode 203. Remove Linked List Elements 2 | /// https://leetcode.com/problems/remove-linked-list-elements/description/ 3 | 4 | class Solution2 { 5 | 6 | public ListNode removeElements(ListNode head, int val) { 7 | 8 | while(head != null && head.val == val) 9 | head = head.next; 10 | 11 | if(head == null) 12 | return head; 13 | 14 | ListNode prev = head; 15 | while(prev.next != null){ 16 | if(prev.next.val == val) 17 | prev.next = prev.next.next; 18 | else 19 | prev = prev.next; 20 | } 21 | 22 | return head; 23 | } 24 | } -------------------------------------------------------------------------------- /07-Set-and-Map/01-Set-Basics-and-BSTSet/src/BSTSet.java: -------------------------------------------------------------------------------- 1 | public class BSTSet> implements Set { 2 | 3 | private BST bst; 4 | 5 | public BSTSet(){ 6 | bst = new BST<>(); 7 | } 8 | 9 | @Override 10 | public int getSize(){ 11 | return bst.size(); 12 | } 13 | 14 | @Override 15 | public boolean isEmpty(){ 16 | return bst.isEmpty(); 17 | } 18 | 19 | @Override 20 | public void add(E e){ 21 | bst.add(e); 22 | } 23 | 24 | @Override 25 | public boolean contains(E e){ 26 | return bst.contains(e); 27 | } 28 | 29 | @Override 30 | public void remove(E e){ 31 | bst.remove(e); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /09-Segment-Tree/05-Segment-Tree-Problems-in-Leetcode/src/NumArray2.java: -------------------------------------------------------------------------------- 1 | /// 303. Range Sum Query - Immutable 2 | /// https://leetcode.com/problems/range-sum-query-immutable/description/ 3 | 4 | public class NumArray2 { 5 | 6 | private int[] sum; // sum[i]存储前i个元素和, sum[0] = 0 7 | // 即sum[i]存储nums[0...i-1]的和 8 | // sum(i, j) = sum[j + 1] - sum[i] 9 | public NumArray2(int[] nums) { 10 | 11 | sum = new int[nums.length + 1]; 12 | sum[0] = 0; 13 | for(int i = 1 ; i < sum.length ; i ++) 14 | sum[i] = sum[i - 1] + nums[i - 1]; 15 | } 16 | 17 | public int sumRange(int i, int j) { 18 | return sum[j + 1] - sum[i]; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /10-Trie/08-Trie-Using-HashMap-and-Array/src/BSTSet.java: -------------------------------------------------------------------------------- 1 | public class BSTSet> implements Set { 2 | 3 | private BST bst; 4 | 5 | public BSTSet(){ 6 | bst = new BST<>(); 7 | } 8 | 9 | @Override 10 | public int getSize(){ 11 | return bst.size(); 12 | } 13 | 14 | @Override 15 | public boolean isEmpty(){ 16 | return bst.isEmpty(); 17 | } 18 | 19 | @Override 20 | public void add(E e){ 21 | bst.add(e); 22 | } 23 | 24 | @Override 25 | public boolean contains(E e){ 26 | return bst.contains(e); 27 | } 28 | 29 | @Override 30 | public void remove(E e){ 31 | bst.remove(e); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ###################### 2 | # OS generated files # 3 | ###################### 4 | .DS_Store 5 | .DS_Store? 6 | ._* 7 | .Spotlight-V100 8 | .Trashes 9 | ehthumbs.db 10 | Thumbs.db 11 | 12 | ##################### 13 | # Java Ignore files # 14 | ##################### 15 | *.class 16 | 17 | ##################### 18 | # C++ Ignore files # 19 | ##################### 20 | *.gch 21 | *.out 22 | 23 | ########################## 24 | # Jetbrains Ignore files # 25 | ########################## 26 | *.iml 27 | .idea/ 28 | 29 | ################# 30 | # Keynote # 31 | ################# 32 | *.key 33 | 34 | ################# 35 | # Course # 36 | ################# 37 | ppt/ 38 | text-contents/ 39 | *.pdf 40 | *.PDF 41 | *.key 42 | -------------------------------------------------------------------------------- /02-Arrays/06-Generic-Data-Structures/src/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static void main(String[] args) { 4 | 5 | Array arr = new Array<>(20); 6 | for(int i = 0 ; i < 10 ; i ++) 7 | arr.addLast(i); 8 | System.out.println(arr); 9 | 10 | arr.add(1, 100); 11 | System.out.println(arr); 12 | 13 | arr.addFirst(-1); 14 | System.out.println(arr); 15 | // [-1, 0, 100, 1, 2, 3, 4, 5, 6, 7, 8, 9] 16 | 17 | arr.remove(2); 18 | System.out.println(arr); 19 | 20 | arr.removeElement(4); 21 | System.out.println(arr); 22 | 23 | arr.removeFirst(); 24 | System.out.println(arr); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /06-Binary-Search-Tree/07-InOrder-and-PostOrder-Traverse-in-BST/src/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static void main(String[] args) { 4 | 5 | BST bst = new BST<>(); 6 | int[] nums = {5, 3, 6, 8, 4, 2}; 7 | for(int num: nums) 8 | bst.add(num); 9 | 10 | ///////////////// 11 | // 5 // 12 | // / \ // 13 | // 3 6 // 14 | // / \ \ // 15 | // 2 4 8 // 16 | ///////////////// 17 | bst.preOrder(); 18 | System.out.println(); 19 | 20 | bst.inOrder(); 21 | System.out.println(); 22 | 23 | bst.postOrder(); 24 | System.out.println(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /02-Arrays/06-Generic-Data-Structures/src/Student.java: -------------------------------------------------------------------------------- 1 | public class Student { 2 | 3 | private String name; 4 | private int score; 5 | 6 | public Student(String studentName, int studentScore){ 7 | name = studentName; 8 | score = studentScore; 9 | } 10 | 11 | @Override 12 | public String toString(){ 13 | return String.format("Student(name: %s, score: %d)", name, score); 14 | } 15 | 16 | public static void main(String[] args) { 17 | 18 | Array arr = new Array<>(); 19 | arr.addLast(new Student("Alice", 100)); 20 | arr.addLast(new Student("Bob", 66)); 21 | arr.addLast(new Student("Charlie", 88)); 22 | System.out.println(arr); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /12-AVL-Tree/08-Map-and-Set-in-AVL-Tree/src/AVLSet.java: -------------------------------------------------------------------------------- 1 | public class AVLSet> implements Set { 2 | 3 | private AVLTree avl; 4 | 5 | public AVLSet(){ 6 | avl = new AVLTree<>(); 7 | } 8 | 9 | @Override 10 | public int getSize(){ 11 | return avl.getSize(); 12 | } 13 | 14 | @Override 15 | public boolean isEmpty(){ 16 | return avl.isEmpty(); 17 | } 18 | 19 | @Override 20 | public void add(E e){ 21 | avl.add(e, null); 22 | } 23 | 24 | @Override 25 | public boolean contains(E e){ 26 | return avl.contains(e); 27 | } 28 | 29 | @Override 30 | public void remove(E e){ 31 | avl.remove(e); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /08-Heap-and-Priority-Queue/04-Extract-and-Sift-Down-in-Heap/src/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.Random; 2 | 3 | public class Main { 4 | 5 | public static void main(String[] args) { 6 | 7 | int n = 1000000; 8 | 9 | MaxHeap maxHeap = new MaxHeap<>(); 10 | Random random = new Random(); 11 | for(int i = 0 ; i < n ; i ++) 12 | maxHeap.add(random.nextInt(Integer.MAX_VALUE)); 13 | 14 | int[] arr = new int[n]; 15 | for(int i = 0 ; i < n ; i ++) 16 | arr[i] = maxHeap.extractMax(); 17 | 18 | for(int i = 1 ; i < n ; i ++) 19 | if(arr[i-1] < arr[i]) 20 | throw new IllegalArgumentException("Error"); 21 | 22 | System.out.println("Test MaxHeap completed."); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /08-Heap-and-Priority-Queue/06-Priority-Queue/src/PriorityQueue.java: -------------------------------------------------------------------------------- 1 | public class PriorityQueue> implements Queue { 2 | 3 | private MaxHeap maxHeap; 4 | 5 | public PriorityQueue(){ 6 | maxHeap = new MaxHeap<>(); 7 | } 8 | 9 | @Override 10 | public int getSize(){ 11 | return maxHeap.size(); 12 | } 13 | 14 | @Override 15 | public boolean isEmpty(){ 16 | return maxHeap.isEmpty(); 17 | } 18 | 19 | @Override 20 | public E getFront(){ 21 | return maxHeap.findMax(); 22 | } 23 | 24 | @Override 25 | public void enqueue(E e){ 26 | maxHeap.add(e); 27 | } 28 | 29 | @Override 30 | public E dequeue(){ 31 | return maxHeap.extractMax(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /05-Recursion/04-LinkedList-and-Recursion/src/Solution5.java: -------------------------------------------------------------------------------- 1 | /// Leetcode 203. Remove Linked List Elements 2 | /// https://leetcode.com/problems/remove-linked-list-elements/description/ 3 | 4 | class Solution5 { 5 | 6 | public ListNode removeElements(ListNode head, int val) { 7 | 8 | if(head == null) 9 | return head; 10 | 11 | head.next = removeElements(head.next, val); 12 | return head.val == val ? head.next : head; 13 | } 14 | 15 | public static void main(String[] args) { 16 | 17 | int[] nums = {1, 2, 6, 3, 4, 5, 6}; 18 | ListNode head = new ListNode(nums); 19 | System.out.println(head); 20 | 21 | ListNode res = (new Solution5()).removeElements(head, 6); 22 | System.out.println(res); 23 | } 24 | } -------------------------------------------------------------------------------- /06-Binary-Search-Tree/10-Level-Traverse-in-BST/src/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static void main(String[] args) { 4 | 5 | BST bst = new BST<>(); 6 | int[] nums = {5, 3, 6, 8, 4, 2}; 7 | for(int num: nums) 8 | bst.add(num); 9 | 10 | ///////////////// 11 | // 5 // 12 | // / \ // 13 | // 3 6 // 14 | // / \ \ // 15 | // 2 4 8 // 16 | ///////////////// 17 | bst.preOrder(); 18 | System.out.println(); 19 | 20 | bst.inOrder(); 21 | System.out.println(); 22 | 23 | bst.postOrder(); 24 | System.out.println(); 25 | 26 | bst.levelOrder(); 27 | System.out.println(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /02-Arrays/09-Amortized-Time-Complexity/src/Main.java: -------------------------------------------------------------------------------- 1 | public class Main { 2 | 3 | public static void main(String[] args) { 4 | 5 | Array arr = new Array<>(); 6 | for(int i = 0 ; i < 10 ; i ++) 7 | arr.addLast(i); 8 | System.out.println(arr); 9 | 10 | arr.add(1, 100); 11 | System.out.println(arr); 12 | 13 | arr.addFirst(-1); 14 | System.out.println(arr); 15 | 16 | arr.remove(2); 17 | System.out.println(arr); 18 | 19 | arr.removeElement(4); 20 | System.out.println(arr); 21 | 22 | arr.removeFirst(); 23 | System.out.println(arr); 24 | 25 | for(int i = 0 ; i < 4 ; i ++){ 26 | arr.removeFirst(); 27 | System.out.println(arr); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /09-Segment-Tree/05-Segment-Tree-Problems-in-Leetcode/src/NumArray.java: -------------------------------------------------------------------------------- 1 | /// 303. Range Sum Query - Immutable 2 | /// https://leetcode.com/problems/range-sum-query-immutable/description/ 3 | 4 | class NumArray { 5 | 6 | private SegmentTree segmentTree; 7 | public NumArray(int[] nums) { 8 | 9 | if(nums.length > 0){ 10 | Integer[] data = new Integer[nums.length]; 11 | for (int i = 0; i < nums.length; i++) 12 | data[i] = nums[i]; 13 | segmentTree = new SegmentTree<>(data, (a, b) -> a + b); 14 | } 15 | 16 | } 17 | 18 | public int sumRange(int i, int j) { 19 | 20 | if(segmentTree == null) 21 | throw new IllegalArgumentException("Segment Tree is null"); 22 | 23 | return segmentTree.query(i, j); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /05-Recursion/04-LinkedList-and-Recursion/src/Solution4.java: -------------------------------------------------------------------------------- 1 | /// Leetcode 203. Remove Linked List Elements 2 | /// https://leetcode.com/problems/remove-linked-list-elements/description/ 3 | 4 | class Solution4 { 5 | 6 | public ListNode removeElements(ListNode head, int val) { 7 | 8 | if(head == null) 9 | return head; 10 | 11 | ListNode res = removeElements(head.next, val); 12 | if(head.val == val) 13 | return res; 14 | else{ 15 | head.next = res; 16 | return head; 17 | } 18 | } 19 | 20 | public static void main(String[] args) { 21 | 22 | int[] nums = {1, 2, 6, 3, 4, 5, 6}; 23 | ListNode head = new ListNode(nums); 24 | System.out.println(head); 25 | 26 | ListNode res = (new Solution4()).removeElements(head, 6); 27 | System.out.println(res); 28 | } 29 | } -------------------------------------------------------------------------------- /07-Set-and-Map/04-TreeSet-and-Set-Problems-in-Leetcode/src/Solution.java: -------------------------------------------------------------------------------- 1 | // Leetcode 804. Unique Morse Code Words 2 | // https://leetcode.com/problems/unique-morse-code-words/description/ 3 | 4 | import java.util.TreeSet; 5 | 6 | public class Solution { 7 | 8 | public int uniqueMorseRepresentations(String[] words) { 9 | 10 | String[] codes = {".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."}; 11 | TreeSet set = new TreeSet<>(); 12 | for(String word: words){ 13 | StringBuilder res = new StringBuilder(); 14 | for(int i = 0 ; i < word.length() ; i ++) 15 | res.append(codes[word.charAt(i) - 'a']); 16 | 17 | set.add(res.toString()); 18 | } 19 | 20 | return set.size(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /07-Set-and-Map/09-Leetcode-Problems-about-Map-and-Set/src/Solution349.java: -------------------------------------------------------------------------------- 1 | /// Leetcode 349. Intersection of Two Arrays 2 | /// https://leetcode.com/problems/intersection-of-two-arrays/description/ 3 | 4 | import java.util.ArrayList; 5 | import java.util.TreeSet; 6 | 7 | class Solution349 { 8 | public int[] intersection(int[] nums1, int[] nums2) { 9 | 10 | TreeSet set = new TreeSet<>(); 11 | for(int num: nums1) 12 | set.add(num); 13 | 14 | ArrayList list = new ArrayList<>(); 15 | for(int num: nums2){ 16 | if(set.contains(num)){ 17 | list.add(num); 18 | set.remove(num); 19 | } 20 | } 21 | 22 | int[] res = new int[list.size()]; 23 | for(int i = 0 ; i < list.size() ; i ++) 24 | res[i] = list.get(i); 25 | return res; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /05-Recursion/01-Linked-List-Problems-in-Leetcode/src/Solution.java: -------------------------------------------------------------------------------- 1 | /// Leetcode 203. Remove Linked List Elements 2 | /// https://leetcode.com/problems/remove-linked-list-elements/description/ 3 | 4 | class Solution { 5 | 6 | public ListNode removeElements(ListNode head, int val) { 7 | 8 | while(head != null && head.val == val){ 9 | ListNode delNode = head; 10 | head = head.next; 11 | delNode.next = null; 12 | } 13 | 14 | if(head == null) 15 | return head; 16 | 17 | ListNode prev = head; 18 | while(prev.next != null){ 19 | if(prev.next.val == val) { 20 | ListNode delNode = prev.next; 21 | prev.next = delNode.next; 22 | delNode.next = null; 23 | } 24 | else 25 | prev = prev.next; 26 | } 27 | 28 | return head; 29 | } 30 | } -------------------------------------------------------------------------------- /09-Segment-Tree/02-Segment-Tree-Basics/src/SegmentTree.java: -------------------------------------------------------------------------------- 1 | public class SegmentTree { 2 | 3 | private E[] tree; 4 | private E[] data; 5 | 6 | public SegmentTree(E[] arr){ 7 | 8 | data = (E[])new Object[arr.length]; 9 | for(int i = 0 ; i < arr.length ; i ++) 10 | data[i] = arr[i]; 11 | 12 | tree = (E[])new Object[4 * arr.length]; 13 | } 14 | 15 | public int getSize(){ 16 | return data.length; 17 | } 18 | 19 | public E get(int index){ 20 | if(index < 0 || index >= data.length) 21 | throw new IllegalArgumentException("Index is illegal."); 22 | return data[index]; 23 | } 24 | 25 | // 返回完全二叉树的数组表示中,一个索引所表示的元素的左孩子节点的索引 26 | private int leftChild(int index){ 27 | return 2*index + 1; 28 | } 29 | 30 | // 返回完全二叉树的数组表示中,一个索引所表示的元素的右孩子节点的索引 31 | private int rightChild(int index){ 32 | return 2*index + 2; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /09-Segment-Tree/05-Segment-Tree-Problems-in-Leetcode/src/NumArray3.java: -------------------------------------------------------------------------------- 1 | /// Leetcode 307. Range Sum Query - Mutable 2 | /// https://leetcode.com/problems/range-sum-query-mutable/description/ 3 | /// 4 | /// 使用sum数组的思路:TLE 5 | class NumArray3 { 6 | 7 | private int[] data; 8 | private int[] sum; 9 | public NumArray3(int[] nums) { 10 | 11 | data = new int[nums.length]; 12 | for(int i = 0 ; i < nums.length ; i ++) 13 | data[i] = nums[i]; 14 | 15 | sum = new int[nums.length + 1]; 16 | sum[0] = 0; 17 | for(int i = 1 ; i <= nums.length ; i ++) 18 | sum[i] = sum[i - 1] + nums[i - 1]; 19 | } 20 | 21 | public int sumRange(int i, int j) { 22 | return sum[j + 1] - sum[i]; 23 | } 24 | 25 | public void update(int index, int val) { 26 | data[index] = val; 27 | for(int i = index + 1 ; i < sum.length ; i ++) 28 | sum[i] = sum[i - 1] + data[i - 1]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /09-Segment-Tree/06-Update-Single-Element-in-Segment-Tree/src/NumArray.java: -------------------------------------------------------------------------------- 1 | /// Leetcode 307. Range Sum Query - Mutable 2 | /// https://leetcode.com/problems/range-sum-query-mutable/description/ 3 | class NumArray { 4 | 5 | private SegmentTree segTree; 6 | public NumArray(int[] nums) { 7 | 8 | if(nums.length != 0){ 9 | Integer[] data = new Integer[nums.length]; 10 | for(int i = 0 ; i < nums.length ; i ++) 11 | data[i] = nums[i]; 12 | segTree = new SegmentTree<>(data, (a, b) -> a + b); 13 | } 14 | } 15 | 16 | public void update(int i, int val) { 17 | if(segTree == null) 18 | throw new IllegalArgumentException("Error"); 19 | segTree.set(i, val); 20 | } 21 | 22 | public int sumRange(int i, int j) { 23 | if(segTree == null) 24 | throw new IllegalArgumentException("Error"); 25 | return segTree.query(i, j); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /05-Recursion/03-Recursion-Basics/src/Solution3.java: -------------------------------------------------------------------------------- 1 | /// Leetcode 203. Remove Linked List Elements 2 | /// https://leetcode.com/problems/remove-linked-list-elements/description/ 3 | 4 | class Solution3 { 5 | 6 | public ListNode removeElements(ListNode head, int val) { 7 | 8 | ListNode dummyHead = new ListNode(-1); 9 | dummyHead.next = head; 10 | 11 | ListNode prev = dummyHead; 12 | while(prev.next != null){ 13 | if(prev.next.val == val) 14 | prev.next = prev.next.next; 15 | else 16 | prev = prev.next; 17 | } 18 | 19 | return dummyHead.next; 20 | } 21 | 22 | public static void main(String[] args) { 23 | 24 | int[] nums = {1, 2, 6, 3, 4, 5, 6}; 25 | ListNode head = new ListNode(nums); 26 | System.out.println(head); 27 | 28 | ListNode res = (new Solution3()).removeElements(head, 6); 29 | System.out.println(res); 30 | } 31 | } -------------------------------------------------------------------------------- /05-Recursion/04-LinkedList-and-Recursion/src/Solution3.java: -------------------------------------------------------------------------------- 1 | /// Leetcode 203. Remove Linked List Elements 2 | /// https://leetcode.com/problems/remove-linked-list-elements/description/ 3 | 4 | class Solution3 { 5 | 6 | public ListNode removeElements(ListNode head, int val) { 7 | 8 | ListNode dummyHead = new ListNode(-1); 9 | dummyHead.next = head; 10 | 11 | ListNode prev = dummyHead; 12 | while(prev.next != null){ 13 | if(prev.next.val == val) 14 | prev.next = prev.next.next; 15 | else 16 | prev = prev.next; 17 | } 18 | 19 | return dummyHead.next; 20 | } 21 | 22 | public static void main(String[] args) { 23 | 24 | int[] nums = {1, 2, 6, 3, 4, 5, 6}; 25 | ListNode head = new ListNode(nums); 26 | System.out.println(head); 27 | 28 | ListNode res = (new Solution3()).removeElements(head, 6); 29 | System.out.println(res); 30 | } 31 | } -------------------------------------------------------------------------------- /05-Recursion/02-Test-Your-LinkedList-Solution/src/Solution3.java: -------------------------------------------------------------------------------- 1 | /// Leetcode 203. Remove Linked List Elements 2 | /// https://leetcode.com/problems/remove-linked-list-elements/description/ 3 | 4 | class Solution3 { 5 | 6 | public ListNode removeElements(ListNode head, int val) { 7 | 8 | ListNode dummyHead = new ListNode(-1); 9 | dummyHead.next = head; 10 | 11 | ListNode prev = dummyHead; 12 | while(prev.next != null){ 13 | if(prev.next.val == val) 14 | prev.next = prev.next.next; 15 | else 16 | prev = prev.next; 17 | } 18 | 19 | return dummyHead.next; 20 | } 21 | 22 | public static void main(String[] args) { 23 | 24 | int[] nums = {1, 2, 6, 3, 4, 5, 6}; 25 | ListNode head = new ListNode(nums); 26 | System.out.println(head); 27 | 28 | ListNode res = (new Solution3()).removeElements(head, 6); 29 | System.out.println(res); 30 | } 31 | } -------------------------------------------------------------------------------- /12-AVL-Tree/08-Map-and-Set-in-AVL-Tree/src/AVLMap.java: -------------------------------------------------------------------------------- 1 | public class AVLMap, V> implements Map { 2 | 3 | private AVLTree avl; 4 | 5 | public AVLMap(){ 6 | avl = new AVLTree<>(); 7 | } 8 | 9 | @Override 10 | public int getSize(){ 11 | return avl.getSize(); 12 | } 13 | 14 | @Override 15 | public boolean isEmpty(){ 16 | return avl.isEmpty(); 17 | } 18 | 19 | @Override 20 | public void add(K key, V value){ 21 | avl.add(key, value); 22 | } 23 | 24 | @Override 25 | public boolean contains(K key){ 26 | return avl.contains(key); 27 | } 28 | 29 | @Override 30 | public V get(K key){ 31 | return avl.get(key); 32 | } 33 | 34 | @Override 35 | public void set(K key, V newValue){ 36 | avl.set(key, newValue); 37 | } 38 | 39 | @Override 40 | public V remove(K key){ 41 | return avl.remove(key); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /05-Recursion/03-Recursion-Basics/src/Solution2.java: -------------------------------------------------------------------------------- 1 | /// Leetcode 203. Remove Linked List Elements 2 | /// https://leetcode.com/problems/remove-linked-list-elements/description/ 3 | 4 | class Solution2 { 5 | 6 | public ListNode removeElements(ListNode head, int val) { 7 | 8 | while(head != null && head.val == val) 9 | head = head.next; 10 | 11 | if(head == null) 12 | return head; 13 | 14 | ListNode prev = head; 15 | while(prev.next != null){ 16 | if(prev.next.val == val) 17 | prev.next = prev.next.next; 18 | else 19 | prev = prev.next; 20 | } 21 | 22 | return head; 23 | } 24 | 25 | public static void main(String[] args) { 26 | 27 | int[] nums = {1, 2, 6, 3, 4, 5, 6}; 28 | ListNode head = new ListNode(nums); 29 | System.out.println(head); 30 | 31 | ListNode res = (new Solution2()).removeElements(head, 6); 32 | System.out.println(res); 33 | } 34 | } -------------------------------------------------------------------------------- /05-Recursion/04-LinkedList-and-Recursion/src/Solution2.java: -------------------------------------------------------------------------------- 1 | /// Leetcode 203. Remove Linked List Elements 2 | /// https://leetcode.com/problems/remove-linked-list-elements/description/ 3 | 4 | class Solution2 { 5 | 6 | public ListNode removeElements(ListNode head, int val) { 7 | 8 | while(head != null && head.val == val) 9 | head = head.next; 10 | 11 | if(head == null) 12 | return head; 13 | 14 | ListNode prev = head; 15 | while(prev.next != null){ 16 | if(prev.next.val == val) 17 | prev.next = prev.next.next; 18 | else 19 | prev = prev.next; 20 | } 21 | 22 | return head; 23 | } 24 | 25 | public static void main(String[] args) { 26 | 27 | int[] nums = {1, 2, 6, 3, 4, 5, 6}; 28 | ListNode head = new ListNode(nums); 29 | System.out.println(head); 30 | 31 | ListNode res = (new Solution2()).removeElements(head, 6); 32 | System.out.println(res); 33 | } 34 | } -------------------------------------------------------------------------------- /05-Recursion/02-Test-Your-LinkedList-Solution/src/Solution2.java: -------------------------------------------------------------------------------- 1 | /// Leetcode 203. Remove Linked List Elements 2 | /// https://leetcode.com/problems/remove-linked-list-elements/description/ 3 | 4 | class Solution2 { 5 | 6 | public ListNode removeElements(ListNode head, int val) { 7 | 8 | while(head != null && head.val == val) 9 | head = head.next; 10 | 11 | if(head == null) 12 | return head; 13 | 14 | ListNode prev = head; 15 | while(prev.next != null){ 16 | if(prev.next.val == val) 17 | prev.next = prev.next.next; 18 | else 19 | prev = prev.next; 20 | } 21 | 22 | return head; 23 | } 24 | 25 | public static void main(String[] args) { 26 | 27 | int[] nums = {1, 2, 6, 3, 4, 5, 6}; 28 | ListNode head = new ListNode(nums); 29 | System.out.println(head); 30 | 31 | ListNode res = (new Solution2()).removeElements(head, 6); 32 | System.out.println(res); 33 | } 34 | } -------------------------------------------------------------------------------- /08-Heap-and-Priority-Queue/02-Heap-Basics/src/MaxHeap.java: -------------------------------------------------------------------------------- 1 | public class MaxHeap> { 2 | 3 | private Array data; 4 | 5 | public MaxHeap(int capacity){ 6 | data = new Array<>(capacity); 7 | } 8 | 9 | public MaxHeap(){ 10 | data = new Array<>(); 11 | } 12 | 13 | // 返回堆中的元素个数 14 | public int size(){ 15 | return data.getSize(); 16 | } 17 | 18 | // 返回一个布尔值, 表示堆中是否为空 19 | public boolean isEmpty(){ 20 | return data.isEmpty(); 21 | } 22 | 23 | // 返回完全二叉树的数组表示中,一个索引所表示的元素的父亲节点的索引 24 | private int parent(int index){ 25 | if(index == 0) 26 | throw new IllegalArgumentException("index-0 doesn't have parent."); 27 | return (index - 1) / 2; 28 | } 29 | 30 | // 返回完全二叉树的数组表示中,一个索引所表示的元素的左孩子节点的索引 31 | private int leftChild(int index){ 32 | return index * 2 + 1; 33 | } 34 | 35 | // 返回完全二叉树的数组表示中,一个索引所表示的元素的右孩子节点的索引 36 | private int rightChild(int index){ 37 | return index * 2 + 2; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /03-Stacks-and-Queues/04-More-about-Leetcode/src/Solution.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | 3 | public boolean isValid(String s) { 4 | 5 | ArrayStack stack = new ArrayStack<>(); 6 | for(int i = 0 ; i < s.length() ; i ++){ 7 | char c = s.charAt(i); 8 | if(c == '(' || c == '[' || c == '{') 9 | stack.push(c); 10 | else{ 11 | if(stack.isEmpty()) 12 | return false; 13 | 14 | char topChar = stack.pop(); 15 | if(c == ')' && topChar != '(') 16 | return false; 17 | if(c == ']' && topChar != '[') 18 | return false; 19 | if(c == '}' && topChar != '{') 20 | return false; 21 | } 22 | } 23 | return stack.isEmpty(); 24 | } 25 | 26 | public static void main(String[] args) { 27 | 28 | System.out.println((new Solution()).isValid("()[]{}")); 29 | System.out.println((new Solution()).isValid("([)]")); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /05-Recursion/03-Recursion-Basics/src/ListNode.java: -------------------------------------------------------------------------------- 1 | //Definition for singly-linked list. 2 | public class ListNode { 3 | 4 | public int val; 5 | public ListNode next; 6 | 7 | public ListNode(int x) { 8 | val = x; 9 | } 10 | 11 | // 链表节点的构造函数 12 | // 使用arr为参数,创建一个链表,当前的ListNode为链表头结点 13 | public ListNode(int[] arr){ 14 | 15 | if(arr == null || arr.length == 0) 16 | throw new IllegalArgumentException("arr can not be empty"); 17 | 18 | this.val = arr[0]; 19 | ListNode cur = this; 20 | for(int i = 1 ; i < arr.length ; i ++){ 21 | cur.next = new ListNode(arr[i]); 22 | cur = cur.next; 23 | } 24 | } 25 | 26 | // 以当前节点为头结点的链表信息字符串 27 | @Override 28 | public String toString(){ 29 | 30 | StringBuilder s = new StringBuilder(); 31 | ListNode cur = this; 32 | while(cur != null){ 33 | s.append(cur.val + "->"); 34 | cur = cur.next; 35 | } 36 | s.append("NULL"); 37 | return s.toString(); 38 | } 39 | } -------------------------------------------------------------------------------- /05-Recursion/04-LinkedList-and-Recursion/src/ListNode.java: -------------------------------------------------------------------------------- 1 | //Definition for singly-linked list. 2 | public class ListNode { 3 | 4 | public int val; 5 | public ListNode next; 6 | 7 | public ListNode(int x) { 8 | val = x; 9 | } 10 | 11 | // 链表节点的构造函数 12 | // 使用arr为参数,创建一个链表,当前的ListNode为链表头结点 13 | public ListNode(int[] arr){ 14 | 15 | if(arr == null || arr.length == 0) 16 | throw new IllegalArgumentException("arr can not be empty"); 17 | 18 | this.val = arr[0]; 19 | ListNode cur = this; 20 | for(int i = 1 ; i < arr.length ; i ++){ 21 | cur.next = new ListNode(arr[i]); 22 | cur = cur.next; 23 | } 24 | } 25 | 26 | // 以当前节点为头结点的链表信息字符串 27 | @Override 28 | public String toString(){ 29 | 30 | StringBuilder s = new StringBuilder(); 31 | ListNode cur = this; 32 | while(cur != null){ 33 | s.append(cur.val + "->"); 34 | cur = cur.next; 35 | } 36 | s.append("NULL"); 37 | return s.toString(); 38 | } 39 | } -------------------------------------------------------------------------------- /05-Recursion/06-Debug-Recursive-Solution/src/ListNode.java: -------------------------------------------------------------------------------- 1 | //Definition for singly-linked list. 2 | public class ListNode { 3 | 4 | public int val; 5 | public ListNode next; 6 | 7 | public ListNode(int x) { 8 | val = x; 9 | } 10 | 11 | // 链表节点的构造函数 12 | // 使用arr为参数,创建一个链表,当前的ListNode为链表头结点 13 | public ListNode(int[] arr){ 14 | 15 | if(arr == null || arr.length == 0) 16 | throw new IllegalArgumentException("arr can not be empty"); 17 | 18 | this.val = arr[0]; 19 | ListNode cur = this; 20 | for(int i = 1 ; i < arr.length ; i ++){ 21 | cur.next = new ListNode(arr[i]); 22 | cur = cur.next; 23 | } 24 | } 25 | 26 | // 以当前节点为头结点的链表信息字符串 27 | @Override 28 | public String toString(){ 29 | 30 | StringBuilder s = new StringBuilder(); 31 | ListNode cur = this; 32 | while(cur != null){ 33 | s.append(cur.val + "->"); 34 | cur = cur.next; 35 | } 36 | s.append("NULL"); 37 | return s.toString(); 38 | } 39 | } -------------------------------------------------------------------------------- /05-Recursion/02-Test-Your-LinkedList-Solution/src/ListNode.java: -------------------------------------------------------------------------------- 1 | //Definition for singly-linked list. 2 | public class ListNode { 3 | 4 | public int val; 5 | public ListNode next; 6 | 7 | public ListNode(int x) { 8 | val = x; 9 | } 10 | 11 | // 链表节点的构造函数 12 | // 使用arr为参数,创建一个链表,当前的ListNode为链表头结点 13 | public ListNode(int[] arr){ 14 | 15 | if(arr == null || arr.length == 0) 16 | throw new IllegalArgumentException("arr can not be empty"); 17 | 18 | this.val = arr[0]; 19 | ListNode cur = this; 20 | for(int i = 1 ; i < arr.length ; i ++){ 21 | cur.next = new ListNode(arr[i]); 22 | cur = cur.next; 23 | } 24 | } 25 | 26 | // 以当前节点为头结点的链表信息字符串 27 | @Override 28 | public String toString(){ 29 | 30 | StringBuilder s = new StringBuilder(); 31 | ListNode cur = this; 32 | while(cur != null){ 33 | s.append(cur.val + "->"); 34 | cur = cur.next; 35 | } 36 | s.append("NULL"); 37 | return s.toString(); 38 | } 39 | } -------------------------------------------------------------------------------- /14-Hash-Table/03-Hash-Function-in-Java/src/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.HashSet; 2 | import java.util.HashMap; 3 | 4 | public class Main { 5 | 6 | public static void main(String[] args) { 7 | 8 | int a = 42; 9 | System.out.println(((Integer)a).hashCode()); 10 | 11 | int b = -42; 12 | System.out.println(((Integer)b).hashCode()); 13 | 14 | double c = 3.1415926; 15 | System.out.println(((Double)c).hashCode()); 16 | 17 | String d = "imooc"; 18 | System.out.println(d.hashCode()); 19 | 20 | System.out.println(Integer.MAX_VALUE + 1); 21 | System.out.println(); 22 | 23 | Student student = new Student(3, 2, "Bobo", "Liu"); 24 | System.out.println(student.hashCode()); 25 | 26 | HashSet set = new HashSet<>(); 27 | set.add(student); 28 | 29 | HashMap scores = new HashMap<>(); 30 | scores.put(student, 100); 31 | 32 | Student student2 = new Student(3, 2, "Bobo", "Liu"); 33 | System.out.println(student2.hashCode()); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /03-Stacks-and-Queues/03-A-Stack-Problem-in-Leetcode/src/Solution.java: -------------------------------------------------------------------------------- 1 | import java.util.Stack; 2 | 3 | class Solution { 4 | 5 | public boolean isValid(String s) { 6 | 7 | Stack stack = new Stack<>(); 8 | for(int i = 0 ; i < s.length() ; i ++){ 9 | char c = s.charAt(i); 10 | if(c == '(' || c == '[' || c == '{') 11 | stack.push(c); 12 | else{ 13 | if(stack.isEmpty()) 14 | return false; 15 | 16 | char topChar = stack.pop(); 17 | if(c == ')' && topChar != '(') 18 | return false; 19 | if(c == ']' && topChar != '[') 20 | return false; 21 | if(c == '}' && topChar != '{') 22 | return false; 23 | } 24 | } 25 | return stack.isEmpty(); 26 | } 27 | 28 | public static void main(String[] args) { 29 | 30 | System.out.println((new Solution()).isValid("()[]{}")); 31 | System.out.println((new Solution()).isValid("([)]")); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /03-Stacks-and-Queues/08-Queues-Comparison/src/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.Random; 2 | 3 | public class Main { 4 | 5 | // 测试使用q运行opCount个enqueueu和dequeue操作所需要的时间,单位:秒 6 | private static double testQueue(Queue q, int opCount){ 7 | 8 | long startTime = System.nanoTime(); 9 | 10 | Random random = new Random(); 11 | for(int i = 0 ; i < opCount ; i ++) 12 | q.enqueue(random.nextInt(Integer.MAX_VALUE)); 13 | for(int i = 0 ; i < opCount ; i ++) 14 | q.dequeue(); 15 | 16 | long endTime = System.nanoTime(); 17 | 18 | return (endTime - startTime) / 1000000000.0; 19 | } 20 | 21 | public static void main(String[] args) { 22 | 23 | int opCount = 100000; 24 | 25 | ArrayQueue arrayQueue = new ArrayQueue<>(); 26 | double time1 = testQueue(arrayQueue, opCount); 27 | System.out.println("ArrayQueue, time: " + time1 + " s"); 28 | 29 | LoopQueue loopQueue = new LoopQueue<>(); 30 | double time2 = testQueue(loopQueue, opCount); 31 | System.out.println("LoopQueue, time: " + time2 + " s"); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /07-Set-and-Map/09-Leetcode-Problems-about-Map-and-Set/src/Solution350.java: -------------------------------------------------------------------------------- 1 | /// Leetcode 350. Intersection of Two Arrays II 2 | /// https://leetcode.com/problems/intersection-of-two-arrays-ii/description/ 3 | 4 | import java.util.ArrayList; 5 | import java.util.TreeMap; 6 | 7 | public class Solution350 { 8 | 9 | public int[] intersect(int[] nums1, int[] nums2) { 10 | 11 | TreeMap map = new TreeMap<>(); 12 | for(int num: nums1){ 13 | if(!map.containsKey(num)) 14 | map.put(num, 1); 15 | else 16 | map.put(num, map.get(num) + 1); 17 | } 18 | 19 | ArrayList res = new ArrayList<>(); 20 | for(int num: nums2){ 21 | if(map.containsKey(num)){ 22 | res.add(num); 23 | map.put(num, map.get(num) - 1); 24 | if(map.get(num) == 0) 25 | map.remove(num); 26 | } 27 | } 28 | 29 | int[] ret = new int[res.size()]; 30 | for(int i = 0 ; i < res.size() ; i ++) 31 | ret[i] = res.get(i); 32 | 33 | return ret; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /10-Trie/02-Trie-Basics/src/Trie.java: -------------------------------------------------------------------------------- 1 | import java.util.TreeMap; 2 | 3 | public class Trie { 4 | 5 | private class Node{ 6 | 7 | public boolean isWord; 8 | public TreeMap next; 9 | 10 | public Node(boolean isWord){ 11 | this.isWord = isWord; 12 | next = new TreeMap<>(); 13 | } 14 | 15 | public Node(){ 16 | this(false); 17 | } 18 | } 19 | 20 | private Node root; 21 | private int size; 22 | 23 | public Trie(){ 24 | root = new Node(); 25 | size = 0; 26 | } 27 | 28 | // 获得Trie中存储的单词数量 29 | public int getSize(){ 30 | return size; 31 | } 32 | 33 | // 向Trie中添加一个新的单词word 34 | public void add(String word){ 35 | 36 | Node cur = root; 37 | for(int i = 0 ; i < word.length() ; i ++){ 38 | char c = word.charAt(i); 39 | if(cur.next.get(c) == null) 40 | cur.next.put(c, new Node()); 41 | cur = cur.next.get(c); 42 | } 43 | 44 | if(!cur.isWord){ 45 | cur.isWord = true; 46 | size ++; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /03-Stacks-and-Queues/06-Loop-Queue/src/LoopQueue.java: -------------------------------------------------------------------------------- 1 | public class LoopQueue implements Queue { 2 | 3 | private E[] data; 4 | private int front, tail; 5 | private int size; // 有兴趣的同学,在完成这一章后,可以思考一下: 6 | // LoopQueue中不声明size,如何完成所有的逻辑? 7 | // 这个问题可能会比大家想象的要难一点点:) 8 | 9 | public LoopQueue(int capacity){ 10 | data = (E[])new Object[capacity + 1]; 11 | front = 0; 12 | tail = 0; 13 | size = 0; 14 | } 15 | 16 | public LoopQueue(){ 17 | this(10); 18 | } 19 | 20 | public int getCapacity(){ 21 | return data.length - 1; 22 | } 23 | 24 | @Override 25 | public boolean isEmpty(){ 26 | return front == tail; 27 | } 28 | 29 | @Override 30 | public int getSize(){ 31 | return size; 32 | } 33 | 34 | // 下一小节再做具体实现 35 | @Override 36 | public void enqueue(E e){ 37 | 38 | } 39 | 40 | // 下一小节再做具体实现 41 | @Override 42 | public E dequeue(){ 43 | return null; 44 | } 45 | 46 | // 下一小节再做具体实现 47 | @Override 48 | public E getFront(){ 49 | return null; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /06-Binary-Search-Tree/Optional-03-Binary-Tree-Classic-Nonrecursive-Traversal/Inorder/src/Solution1.java: -------------------------------------------------------------------------------- 1 | /// Source : https://leetcode.com/problems/binary-tree-inorder-traversal/solution/ 2 | /// Author : liuyubobobo 3 | /// Time : 2018-05-30 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.Stack; 8 | 9 | // Classic Non-Recursive algorithm for inorder traversal 10 | // Time Complexity: O(n), n is the node number in the tree 11 | // Space Complexity: O(h), h is the height of the tree 12 | public class Solution1 { 13 | 14 | public List inorderTraversal(TreeNode root) { 15 | 16 | ArrayList res = new ArrayList(); 17 | if(root == null) 18 | return res; 19 | 20 | Stack stack = new Stack<>(); 21 | TreeNode cur = root; 22 | while(cur != null || !stack.empty()){ 23 | 24 | while(cur != null){ 25 | stack.push(cur); 26 | cur = cur.left; 27 | } 28 | 29 | cur = stack.pop(); 30 | res.add(cur.val); 31 | cur = cur.right; 32 | } 33 | return res; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /13-Red-Black-Tree/08-The-Performance-of-Red-Black-Tree/src/Main3.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.Random; 3 | 4 | public class Main3 { 5 | 6 | public static void main(String[] args) { 7 | 8 | int n = 20000000; 9 | 10 | ArrayList testData = new ArrayList<>(n); 11 | for(int i = 0 ; i < n ; i ++) 12 | testData.add(i); 13 | 14 | // Test AVL 15 | long startTime = System.nanoTime(); 16 | 17 | AVLTree avl = new AVLTree<>(); 18 | for (Integer x: testData) 19 | avl.add(x, null); 20 | 21 | long endTime = System.nanoTime(); 22 | 23 | double time = (endTime - startTime) / 1000000000.0; 24 | System.out.println("AVL: " + time + " s"); 25 | 26 | 27 | // Test RBTree 28 | startTime = System.nanoTime(); 29 | 30 | RBTree rbt = new RBTree<>(); 31 | for (Integer x: testData) 32 | rbt.add(x, null); 33 | 34 | endTime = System.nanoTime(); 35 | 36 | time = (endTime - startTime) / 1000000000.0; 37 | System.out.println("RBTree: " + time + " s"); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /06-Binary-Search-Tree/Optional-03-Binary-Tree-Classic-Nonrecursive-Traversal/Preorder/src/Solution2.java: -------------------------------------------------------------------------------- 1 | /// Source : https://leetcode.com/problems/binary-tree-preorder-traversal/description/ 2 | /// Author : liuyubobobo 3 | /// Time : 2018-05-30 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.Stack; 8 | 9 | // Another Classic Non-Recursive algorithm for preorder traversal 10 | // Time Complexity: O(n), n is the node number in the tree 11 | // Space Complexity: O(h), h is the height of the tree 12 | public class Solution2 { 13 | 14 | public List preorderTraversal(TreeNode root) { 15 | 16 | ArrayList res = new ArrayList(); 17 | if(root == null) 18 | return res; 19 | 20 | Stack stack = new Stack(); 21 | TreeNode cur = root; 22 | while(cur != null || !stack.isEmpty()){ 23 | while(cur != null){ 24 | res.add(cur.val); 25 | stack.push(cur); 26 | cur = cur.left; 27 | } 28 | 29 | cur = stack.pop(); 30 | cur = cur.right; 31 | } 32 | return res; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /06-Binary-Search-Tree/04-Improved-Add-Elements-in-BST/src/BST.java: -------------------------------------------------------------------------------- 1 | public class BST> { 2 | 3 | private class Node { 4 | public E e; 5 | public Node left, right; 6 | 7 | public Node(E e) { 8 | this.e = e; 9 | left = null; 10 | right = null; 11 | } 12 | } 13 | 14 | private Node root; 15 | private int size; 16 | 17 | public BST(){ 18 | root = null; 19 | size = 0; 20 | } 21 | 22 | public int size(){ 23 | return size; 24 | } 25 | 26 | public boolean isEmpty(){ 27 | return size == 0; 28 | } 29 | 30 | // 向二分搜索树中添加新的元素e 31 | public void add(E e){ 32 | root = add(root, e); 33 | } 34 | 35 | // 向以node为根的二分搜索树中插入元素e,递归算法 36 | // 返回插入新节点后二分搜索树的根 37 | private Node add(Node node, E e){ 38 | if(node == null){ 39 | size ++; 40 | return new Node(e); 41 | } 42 | 43 | if(e.compareTo(node.e) < 0) 44 | node.left = add(node.left, e); 45 | else if(e.compareTo(node.e) > 0) 46 | node.right = add(node.right, e); 47 | 48 | return node; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /06-Binary-Search-Tree/Optional-03-Binary-Tree-Classic-Nonrecursive-Traversal/Preorder/src/Solution1.java: -------------------------------------------------------------------------------- 1 | /// Source : https://leetcode.com/problems/binary-tree-preorder-traversal/description/ 2 | /// Author : liuyubobobo 3 | /// Time : 2017-11-17 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.Stack; 8 | 9 | // Classic Non-Recursive algorithm for preorder traversal 10 | // Time Complexity: O(n), n is the node number in the tree 11 | // Space Complexity: O(h), h is the height of the tree 12 | public class Solution1 { 13 | 14 | public List preorderTraversal(TreeNode root) { 15 | 16 | ArrayList res = new ArrayList(); 17 | if(root == null) 18 | return res; 19 | 20 | Stack stack = new Stack(); 21 | stack.push(root); 22 | while(!stack.empty()){ 23 | TreeNode curNode = stack.pop(); 24 | res.add(curNode.val); 25 | 26 | if(curNode.right != null) 27 | stack.push(curNode.right); 28 | if(curNode.left != null) 29 | stack.push(curNode.left); 30 | } 31 | return res; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /07-Set-and-Map/01-Set-Basics-and-BSTSet/src/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class Main { 4 | 5 | public static void main(String[] args) { 6 | 7 | System.out.println("Pride and Prejudice"); 8 | 9 | ArrayList words1 = new ArrayList<>(); 10 | if(FileOperation.readFile("pride-and-prejudice.txt", words1)) { 11 | System.out.println("Total words: " + words1.size()); 12 | 13 | BSTSet set1 = new BSTSet<>(); 14 | for (String word : words1) 15 | set1.add(word); 16 | System.out.println("Total different words: " + set1.getSize()); 17 | } 18 | 19 | System.out.println(); 20 | 21 | 22 | System.out.println("A Tale of Two Cities"); 23 | 24 | ArrayList words2 = new ArrayList<>(); 25 | if(FileOperation.readFile("a-tale-of-two-cities.txt", words2)){ 26 | System.out.println("Total words: " + words2.size()); 27 | 28 | BSTSet set2 = new BSTSet<>(); 29 | for(String word: words2) 30 | set2.add(word); 31 | System.out.println("Total different words: " + set2.getSize()); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /05-Recursion/03-Recursion-Basics/src/Solution.java: -------------------------------------------------------------------------------- 1 | /// Leetcode 203. Remove Linked List Elements 2 | /// https://leetcode.com/problems/remove-linked-list-elements/description/ 3 | 4 | class Solution { 5 | 6 | public ListNode removeElements(ListNode head, int val) { 7 | 8 | while(head != null && head.val == val){ 9 | ListNode delNode = head; 10 | head = head.next; 11 | delNode.next = null; 12 | } 13 | 14 | if(head == null) 15 | return head; 16 | 17 | ListNode prev = head; 18 | while(prev.next != null){ 19 | if(prev.next.val == val) { 20 | ListNode delNode = prev.next; 21 | prev.next = delNode.next; 22 | delNode.next = null; 23 | } 24 | else 25 | prev = prev.next; 26 | } 27 | 28 | return head; 29 | } 30 | 31 | public static void main(String[] args) { 32 | 33 | int[] nums = {1, 2, 6, 3, 4, 5, 6}; 34 | ListNode head = new ListNode(nums); 35 | System.out.println(head); 36 | 37 | ListNode res = (new Solution()).removeElements(head, 6); 38 | System.out.println(res); 39 | } 40 | } -------------------------------------------------------------------------------- /05-Recursion/04-LinkedList-and-Recursion/src/Solution.java: -------------------------------------------------------------------------------- 1 | /// Leetcode 203. Remove Linked List Elements 2 | /// https://leetcode.com/problems/remove-linked-list-elements/description/ 3 | 4 | class Solution { 5 | 6 | public ListNode removeElements(ListNode head, int val) { 7 | 8 | while(head != null && head.val == val){ 9 | ListNode delNode = head; 10 | head = head.next; 11 | delNode.next = null; 12 | } 13 | 14 | if(head == null) 15 | return head; 16 | 17 | ListNode prev = head; 18 | while(prev.next != null){ 19 | if(prev.next.val == val) { 20 | ListNode delNode = prev.next; 21 | prev.next = delNode.next; 22 | delNode.next = null; 23 | } 24 | else 25 | prev = prev.next; 26 | } 27 | 28 | return head; 29 | } 30 | 31 | public static void main(String[] args) { 32 | 33 | int[] nums = {1, 2, 6, 3, 4, 5, 6}; 34 | ListNode head = new ListNode(nums); 35 | System.out.println(head); 36 | 37 | ListNode res = (new Solution()).removeElements(head, 6); 38 | System.out.println(res); 39 | } 40 | } -------------------------------------------------------------------------------- /06-Binary-Search-Tree/Optional-03-Binary-Tree-Classic-Nonrecursive-Traversal/Inorder/src/Solution2.java: -------------------------------------------------------------------------------- 1 | /// Source : https://leetcode.com/problems/binary-tree-inorder-traversal/solution/ 2 | /// Author : liuyubobobo 3 | /// Time : 2018-05-30 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.Stack; 8 | 9 | // Another Classic Non-Recursive algorithm for inorder traversal 10 | // Time Complexity: O(n), n is the node number in the tree 11 | // Space Complexity: O(h), h is the height of the tree 12 | public class Solution2 { 13 | 14 | public List inorderTraversal(TreeNode root) { 15 | 16 | ArrayList res = new ArrayList(); 17 | if(root == null) 18 | return res; 19 | 20 | Stack stack = new Stack<>(); 21 | TreeNode cur = root; 22 | while(cur != null || !stack.empty()){ 23 | 24 | if(cur != null){ 25 | stack.push(cur); 26 | cur = cur.left; 27 | } 28 | else{ 29 | cur = stack.pop(); 30 | res.add(cur.val); 31 | cur = cur.right; 32 | } 33 | } 34 | return res; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /05-Recursion/02-Test-Your-LinkedList-Solution/src/Solution.java: -------------------------------------------------------------------------------- 1 | /// Leetcode 203. Remove Linked List Elements 2 | /// https://leetcode.com/problems/remove-linked-list-elements/description/ 3 | 4 | class Solution { 5 | 6 | public ListNode removeElements(ListNode head, int val) { 7 | 8 | while(head != null && head.val == val){ 9 | ListNode delNode = head; 10 | head = head.next; 11 | delNode.next = null; 12 | } 13 | 14 | if(head == null) 15 | return head; 16 | 17 | ListNode prev = head; 18 | while(prev.next != null){ 19 | if(prev.next.val == val) { 20 | ListNode delNode = prev.next; 21 | prev.next = delNode.next; 22 | delNode.next = null; 23 | } 24 | else 25 | prev = prev.next; 26 | } 27 | 28 | return head; 29 | } 30 | 31 | public static void main(String[] args) { 32 | 33 | int[] nums = {1, 2, 6, 3, 4, 5, 6}; 34 | ListNode head = new ListNode(nums); 35 | System.out.println(head); 36 | 37 | ListNode res = (new Solution()).removeElements(head, 6); 38 | System.out.println(res); 39 | } 40 | } -------------------------------------------------------------------------------- /06-Binary-Search-Tree/Optional-03-Binary-Tree-Classic-Nonrecursive-Traversal/Preorder/src/Solution3.java: -------------------------------------------------------------------------------- 1 | /// Source : https://leetcode.com/problems/binary-tree-preorder-traversal/description/ 2 | /// Author : liuyubobobo 3 | /// Time : 2018-05-30 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.Stack; 8 | 9 | // Another Classic Non-Recursive algorithm for preorder traversal 10 | // Time Complexity: O(n), n is the node number in the tree 11 | // Space Complexity: O(h), h is the height of the tree 12 | public class Solution3 { 13 | 14 | public List preorderTraversal(TreeNode root) { 15 | 16 | ArrayList res = new ArrayList(); 17 | if(root == null) 18 | return res; 19 | 20 | Stack stack = new Stack(); 21 | TreeNode cur = root; 22 | while(cur != null || !stack.isEmpty()){ 23 | if(cur != null){ 24 | res.add(cur.val); 25 | stack.push(cur); 26 | cur = cur.left; 27 | } 28 | else{ 29 | cur = stack.pop(); 30 | cur = cur.right; 31 | } 32 | } 33 | return res; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /04-Linked-List/06-Implement-Stack-in-LinkedList/src/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.Random; 2 | 3 | public class Main { 4 | 5 | // 测试使用stack运行opCount个push和pop操作所需要的时间,单位:秒 6 | private static double testStack(Stack stack, int opCount){ 7 | 8 | long startTime = System.nanoTime(); 9 | 10 | Random random = new Random(); 11 | for(int i = 0 ; i < opCount ; i ++) 12 | stack.push(random.nextInt(Integer.MAX_VALUE)); 13 | for(int i = 0 ; i < opCount ; i ++) 14 | stack.pop(); 15 | 16 | long endTime = System.nanoTime(); 17 | 18 | return (endTime - startTime) / 1000000000.0; 19 | } 20 | 21 | public static void main(String[] args) { 22 | 23 | int opCount = 100000; 24 | 25 | ArrayStack arrayStack = new ArrayStack<>(); 26 | double time1 = testStack(arrayStack, opCount); 27 | System.out.println("ArrayStack, time: " + time1 + " s"); 28 | 29 | LinkedListStack linkedListStack = new LinkedListStack<>(); 30 | double time2 = testStack(linkedListStack, opCount); 31 | System.out.println("LinkedListStack, time: " + time2 + " s"); 32 | 33 | // 其实这个时间比较很复杂,因为LinkedListStack中包含更多的new操作 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /06-Binary-Search-Tree/09-Non-Recursion-Preorder-Traverse-in-BST/src/Solution.java: -------------------------------------------------------------------------------- 1 | /// Leetcode 144. Binary Tree Preorder Traversal 2 | /// https://leetcode.com/problems/binary-tree-preorder-traversal/description/ 3 | /// 4 | /// 课程中在这里暂时没有介绍这个问题 5 | /// 该代码主要用于使用Leetcode上的问题测试我们的BST类 6 | /// 该测试主要测试前序遍历的非递归写法 7 | 8 | import java.util.List; 9 | import java.util.LinkedList; 10 | import java.util.Stack; 11 | 12 | public class Solution { 13 | 14 | // Definition for a binary tree node. 15 | public class TreeNode { 16 | int val; 17 | TreeNode left; 18 | TreeNode right; 19 | TreeNode(int x) { val = x; } 20 | } 21 | 22 | public List preorderTraversal(TreeNode root) { 23 | 24 | List res = new LinkedList<>(); 25 | if(root == null) 26 | return res; 27 | 28 | Stack stack = new Stack<>(); 29 | stack.push(root); 30 | while(!stack.isEmpty()){ 31 | TreeNode cur = stack.pop(); 32 | res.add(cur.val); 33 | 34 | if(cur.right != null) 35 | stack.push(cur.right); 36 | if(cur.left != null) 37 | stack.push(cur.left); 38 | } 39 | 40 | return res; 41 | } 42 | } -------------------------------------------------------------------------------- /06-Binary-Search-Tree/Optional-03-Binary-Tree-Classic-Nonrecursive-Traversal/Postorder/src/Solution2.java: -------------------------------------------------------------------------------- 1 | /// Source : https://leetcode.com/problems/binary-tree-postorder-traversal/description/ 2 | /// Author : liuyubobobo 3 | /// Time : 2018-05-30 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.Stack; 8 | 9 | // Non-Recursive 10 | // Using two stacks, Reverse Preorder Traversal! 11 | // 12 | // Time Complexity: O(n) 13 | // Space Complexity: O(n) 14 | public class Solution2 { 15 | 16 | public List postorderTraversal(TreeNode root) { 17 | 18 | ArrayList res = new ArrayList(); 19 | if(root == null) 20 | return res; 21 | 22 | Stack stack = new Stack<>(); 23 | Stack output = new Stack<>(); 24 | 25 | stack.push(root); 26 | while(!stack.empty()){ 27 | 28 | TreeNode cur = stack.pop(); 29 | output.push(cur.val); 30 | 31 | if(cur.left != null) 32 | stack.push(cur.left); 33 | if(cur.right != null) 34 | stack.push(cur.right); 35 | } 36 | 37 | while(!output.empty()) 38 | res.add(output.pop()); 39 | return res; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /06-Binary-Search-Tree/Optional-03-Binary-Tree-Classic-Nonrecursive-Traversal/Postorder/src/Solution3.java: -------------------------------------------------------------------------------- 1 | /// Source : https://leetcode.com/problems/binary-tree-postorder-traversal/description/ 2 | /// Author : liuyubobobo 3 | /// Time : 2018-07-03 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.Stack; 8 | import java.util.LinkedList; 9 | 10 | // Non-Recursive 11 | // Using two stacks, Reverse Preorder Traversal! 12 | // 13 | // Time Complexity: O(n) 14 | // Space Complexity: O(n) 15 | public class Solution3 { 16 | 17 | public List postorderTraversal(TreeNode root){ 18 | 19 | Stack stack = new Stack<>(); 20 | LinkedList output = new LinkedList<>(); 21 | 22 | TreeNode p = root; 23 | while(p != null || !stack.isEmpty()){ 24 | if(p != null){ 25 | stack.push(p); 26 | output.push(p); 27 | p = p.right; 28 | } 29 | else{ 30 | p = stack.pop(); 31 | p = p.left; 32 | } 33 | } 34 | 35 | ArrayList res = new ArrayList<>(); 36 | while(!output.isEmpty()) 37 | res.add(output.pop().val); 38 | return res; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /11-Union-Find/02-Quick-Find/src/UnionFind1.java: -------------------------------------------------------------------------------- 1 | // 我们的第一版Union-Find 2 | public class UnionFind1 implements UF { 3 | 4 | private int[] id; // 我们的第一版Union-Find本质就是一个数组 5 | 6 | public UnionFind1(int size) { 7 | 8 | id = new int[size]; 9 | 10 | // 初始化, 每一个id[i]指向自己, 没有合并的元素 11 | for (int i = 0; i < size; i++) 12 | id[i] = i; 13 | } 14 | 15 | @Override 16 | public int getSize(){ 17 | return id.length; 18 | } 19 | 20 | // 查找元素p所对应的集合编号 21 | // O(1)复杂度 22 | private int find(int p) { 23 | if(p < 0 || p >= id.length) 24 | throw new IllegalArgumentException("p is out of bound."); 25 | 26 | return id[p]; 27 | } 28 | 29 | // 查看元素p和元素q是否所属一个集合 30 | // O(1)复杂度 31 | @Override 32 | public boolean isConnected(int p, int q) { 33 | return find(p) == find(q); 34 | } 35 | 36 | // 合并元素p和元素q所属的集合 37 | // O(n) 复杂度 38 | @Override 39 | public void unionElements(int p, int q) { 40 | 41 | int pID = find(p); 42 | int qID = find(q); 43 | 44 | if (pID == qID) 45 | return; 46 | 47 | // 合并过程需要遍历一遍所有元素, 将两个元素的所属集合编号合并 48 | for (int i = 0; i < id.length; i++) 49 | if (id[i] == pID) 50 | id[i] = qID; 51 | } 52 | } -------------------------------------------------------------------------------- /07-Set-and-Map/03-Time-Complexity-of-Set/src/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class Main { 4 | 5 | private static double testSet(Set set, String filename){ 6 | 7 | long startTime = System.nanoTime(); 8 | 9 | System.out.println(filename); 10 | ArrayList words = new ArrayList<>(); 11 | if(FileOperation.readFile(filename, words)) { 12 | System.out.println("Total words: " + words.size()); 13 | 14 | for (String word : words) 15 | set.add(word); 16 | System.out.println("Total different words: " + set.getSize()); 17 | } 18 | long endTime = System.nanoTime(); 19 | 20 | return (endTime - startTime) / 1000000000.0; 21 | } 22 | 23 | public static void main(String[] args) { 24 | 25 | String filename = "pride-and-prejudice.txt"; 26 | 27 | BSTSet bstSet = new BSTSet<>(); 28 | double time1 = testSet(bstSet, filename); 29 | System.out.println("BST Set: " + time1 + " s"); 30 | 31 | System.out.println(); 32 | 33 | LinkedListSet linkedListSet = new LinkedListSet<>(); 34 | double time2 = testSet(linkedListSet, filename); 35 | System.out.println("Linked List Set: " + time2 + " s"); 36 | 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /11-Union-Find/03-Quick-Union/src/UnionFind1.java: -------------------------------------------------------------------------------- 1 | // 我们的第一版Union-Find 2 | public class UnionFind1 implements UF { 3 | 4 | private int[] id; // 我们的第一版Union-Find本质就是一个数组 5 | 6 | public UnionFind1(int size) { 7 | 8 | id = new int[size]; 9 | 10 | // 初始化, 每一个id[i]指向自己, 没有合并的元素 11 | for (int i = 0; i < size; i++) 12 | id[i] = i; 13 | } 14 | 15 | @Override 16 | public int getSize(){ 17 | return id.length; 18 | } 19 | 20 | // 查找元素p所对应的集合编号 21 | // O(1)复杂度 22 | private int find(int p) { 23 | if(p < 0 || p >= id.length) 24 | throw new IllegalArgumentException("p is out of bound."); 25 | 26 | return id[p]; 27 | } 28 | 29 | // 查看元素p和元素q是否所属一个集合 30 | // O(1)复杂度 31 | @Override 32 | public boolean isConnected(int p, int q) { 33 | return find(p) == find(q); 34 | } 35 | 36 | // 合并元素p和元素q所属的集合 37 | // O(n) 复杂度 38 | @Override 39 | public void unionElements(int p, int q) { 40 | 41 | int pID = find(p); 42 | int qID = find(q); 43 | 44 | if (pID == qID) 45 | return; 46 | 47 | // 合并过程需要遍历一遍所有元素, 将两个元素的所属集合编号合并 48 | for (int i = 0; i < id.length; i++) 49 | if (id[i] == pID) 50 | id[i] = qID; 51 | } 52 | } -------------------------------------------------------------------------------- /11-Union-Find/04-Optimized-by-Size/src/UnionFind1.java: -------------------------------------------------------------------------------- 1 | // 我们的第一版Union-Find 2 | public class UnionFind1 implements UF { 3 | 4 | private int[] id; // 我们的第一版Union-Find本质就是一个数组 5 | 6 | public UnionFind1(int size) { 7 | 8 | id = new int[size]; 9 | 10 | // 初始化, 每一个id[i]指向自己, 没有合并的元素 11 | for (int i = 0; i < size; i++) 12 | id[i] = i; 13 | } 14 | 15 | @Override 16 | public int getSize(){ 17 | return id.length; 18 | } 19 | 20 | // 查找元素p所对应的集合编号 21 | // O(1)复杂度 22 | private int find(int p) { 23 | if(p < 0 || p >= id.length) 24 | throw new IllegalArgumentException("p is out of bound."); 25 | 26 | return id[p]; 27 | } 28 | 29 | // 查看元素p和元素q是否所属一个集合 30 | // O(1)复杂度 31 | @Override 32 | public boolean isConnected(int p, int q) { 33 | return find(p) == find(q); 34 | } 35 | 36 | // 合并元素p和元素q所属的集合 37 | // O(n) 复杂度 38 | @Override 39 | public void unionElements(int p, int q) { 40 | 41 | int pID = find(p); 42 | int qID = find(q); 43 | 44 | if (pID == qID) 45 | return; 46 | 47 | // 合并过程需要遍历一遍所有元素, 将两个元素的所属集合编号合并 48 | for (int i = 0; i < id.length; i++) 49 | if (id[i] == pID) 50 | id[i] = qID; 51 | } 52 | } -------------------------------------------------------------------------------- /11-Union-Find/05-Optimized-by-Rank/src/UnionFind1.java: -------------------------------------------------------------------------------- 1 | // 我们的第一版Union-Find 2 | public class UnionFind1 implements UF { 3 | 4 | private int[] id; // 我们的第一版Union-Find本质就是一个数组 5 | 6 | public UnionFind1(int size) { 7 | 8 | id = new int[size]; 9 | 10 | // 初始化, 每一个id[i]指向自己, 没有合并的元素 11 | for (int i = 0; i < size; i++) 12 | id[i] = i; 13 | } 14 | 15 | @Override 16 | public int getSize(){ 17 | return id.length; 18 | } 19 | 20 | // 查找元素p所对应的集合编号 21 | // O(1)复杂度 22 | private int find(int p) { 23 | if(p < 0 || p >= id.length) 24 | throw new IllegalArgumentException("p is out of bound."); 25 | 26 | return id[p]; 27 | } 28 | 29 | // 查看元素p和元素q是否所属一个集合 30 | // O(1)复杂度 31 | @Override 32 | public boolean isConnected(int p, int q) { 33 | return find(p) == find(q); 34 | } 35 | 36 | // 合并元素p和元素q所属的集合 37 | // O(n) 复杂度 38 | @Override 39 | public void unionElements(int p, int q) { 40 | 41 | int pID = find(p); 42 | int qID = find(q); 43 | 44 | if (pID == qID) 45 | return; 46 | 47 | // 合并过程需要遍历一遍所有元素, 将两个元素的所属集合编号合并 48 | for (int i = 0; i < id.length; i++) 49 | if (id[i] == pID) 50 | id[i] = qID; 51 | } 52 | } -------------------------------------------------------------------------------- /11-Union-Find/06-Path-Compression/src/UnionFind1.java: -------------------------------------------------------------------------------- 1 | // 我们的第一版Union-Find 2 | public class UnionFind1 implements UF { 3 | 4 | private int[] id; // 我们的第一版Union-Find本质就是一个数组 5 | 6 | public UnionFind1(int size) { 7 | 8 | id = new int[size]; 9 | 10 | // 初始化, 每一个id[i]指向自己, 没有合并的元素 11 | for (int i = 0; i < size; i++) 12 | id[i] = i; 13 | } 14 | 15 | @Override 16 | public int getSize(){ 17 | return id.length; 18 | } 19 | 20 | // 查找元素p所对应的集合编号 21 | // O(1)复杂度 22 | private int find(int p) { 23 | if(p < 0 || p >= id.length) 24 | throw new IllegalArgumentException("p is out of bound."); 25 | 26 | return id[p]; 27 | } 28 | 29 | // 查看元素p和元素q是否所属一个集合 30 | // O(1)复杂度 31 | @Override 32 | public boolean isConnected(int p, int q) { 33 | return find(p) == find(q); 34 | } 35 | 36 | // 合并元素p和元素q所属的集合 37 | // O(n) 复杂度 38 | @Override 39 | public void unionElements(int p, int q) { 40 | 41 | int pID = find(p); 42 | int qID = find(q); 43 | 44 | if (pID == qID) 45 | return; 46 | 47 | // 合并过程需要遍历一遍所有元素, 将两个元素的所属集合编号合并 48 | for (int i = 0; i < id.length; i++) 49 | if (id[i] == pID) 50 | id[i] = qID; 51 | } 52 | } -------------------------------------------------------------------------------- /04-Linked-List/06-Implement-Stack-in-LinkedList/src/LinkedListStack.java: -------------------------------------------------------------------------------- 1 | public class LinkedListStack implements Stack { 2 | 3 | private LinkedList list; 4 | 5 | public LinkedListStack(){ 6 | list = new LinkedList<>(); 7 | } 8 | 9 | @Override 10 | public int getSize(){ 11 | return list.getSize(); 12 | } 13 | 14 | @Override 15 | public boolean isEmpty(){ 16 | return list.isEmpty(); 17 | } 18 | 19 | @Override 20 | public void push(E e){ 21 | list.addFirst(e); 22 | } 23 | 24 | @Override 25 | public E pop(){ 26 | return list.removeFirst(); 27 | } 28 | 29 | @Override 30 | public E peek(){ 31 | return list.getFirst(); 32 | } 33 | 34 | @Override 35 | public String toString(){ 36 | StringBuilder res = new StringBuilder(); 37 | res.append("Stack: top "); 38 | res.append(list); 39 | return res.toString(); 40 | } 41 | 42 | public static void main(String[] args) { 43 | 44 | LinkedListStack stack = new LinkedListStack<>(); 45 | 46 | for(int i = 0 ; i < 5 ; i ++){ 47 | stack.push(i); 48 | System.out.println(stack); 49 | } 50 | 51 | stack.pop(); 52 | System.out.println(stack); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /11-Union-Find/07-More-about-Union-Find/src/UnionFind1.java: -------------------------------------------------------------------------------- 1 | // 我们的第一版Union-Find 2 | public class UnionFind1 implements UF { 3 | 4 | private int[] id; // 我们的第一版Union-Find本质就是一个数组 5 | 6 | public UnionFind1(int size) { 7 | 8 | id = new int[size]; 9 | 10 | // 初始化, 每一个id[i]指向自己, 没有合并的元素 11 | for (int i = 0; i < size; i++) 12 | id[i] = i; 13 | } 14 | 15 | @Override 16 | public int getSize(){ 17 | return id.length; 18 | } 19 | 20 | // 查找元素p所对应的集合编号 21 | // O(1)复杂度 22 | private int find(int p) { 23 | if(p < 0 || p >= id.length) 24 | throw new IllegalArgumentException("p is out of bound."); 25 | 26 | return id[p]; 27 | } 28 | 29 | // 查看元素p和元素q是否所属一个集合 30 | // O(1)复杂度 31 | @Override 32 | public boolean isConnected(int p, int q) { 33 | return find(p) == find(q); 34 | } 35 | 36 | // 合并元素p和元素q所属的集合 37 | // O(n) 复杂度 38 | @Override 39 | public void unionElements(int p, int q) { 40 | 41 | int pID = find(p); 42 | int qID = find(q); 43 | 44 | if (pID == qID) 45 | return; 46 | 47 | // 合并过程需要遍历一遍所有元素, 将两个元素的所属集合编号合并 48 | for (int i = 0; i < id.length; i++) 49 | if (id[i] == pID) 50 | id[i] = qID; 51 | } 52 | } -------------------------------------------------------------------------------- /03-Stacks-and-Queues/02-Array-Stack/src/ArrayStack.java: -------------------------------------------------------------------------------- 1 | public class ArrayStack implements Stack { 2 | 3 | private Array array; 4 | 5 | public ArrayStack(int capacity){ 6 | array = new Array<>(capacity); 7 | } 8 | 9 | public ArrayStack(){ 10 | array = new Array<>(); 11 | } 12 | 13 | @Override 14 | public int getSize(){ 15 | return array.getSize(); 16 | } 17 | 18 | @Override 19 | public boolean isEmpty(){ 20 | return array.isEmpty(); 21 | } 22 | 23 | public int getCapacity(){ 24 | return array.getCapacity(); 25 | } 26 | 27 | @Override 28 | public void push(E e){ 29 | array.addLast(e); 30 | } 31 | 32 | @Override 33 | public E pop(){ 34 | return array.removeLast(); 35 | } 36 | 37 | @Override 38 | public E peek(){ 39 | return array.getLast(); 40 | } 41 | 42 | @Override 43 | public String toString(){ 44 | StringBuilder res = new StringBuilder(); 45 | res.append("Stack: "); 46 | res.append('['); 47 | for(int i = 0 ; i < array.getSize() ; i ++){ 48 | res.append(array.get(i)); 49 | if(i != array.getSize() - 1) 50 | res.append(", "); 51 | } 52 | res.append("] top"); 53 | return res.toString(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /03-Stacks-and-Queues/04-More-about-Leetcode/src/ArrayStack.java: -------------------------------------------------------------------------------- 1 | public class ArrayStack implements Stack { 2 | 3 | private Array array; 4 | 5 | public ArrayStack(int capacity){ 6 | array = new Array<>(capacity); 7 | } 8 | 9 | public ArrayStack(){ 10 | array = new Array<>(); 11 | } 12 | 13 | @Override 14 | public int getSize(){ 15 | return array.getSize(); 16 | } 17 | 18 | @Override 19 | public boolean isEmpty(){ 20 | return array.isEmpty(); 21 | } 22 | 23 | public int getCapacity(){ 24 | return array.getCapacity(); 25 | } 26 | 27 | @Override 28 | public void push(E e){ 29 | array.addLast(e); 30 | } 31 | 32 | @Override 33 | public E pop(){ 34 | return array.removeLast(); 35 | } 36 | 37 | @Override 38 | public E peek(){ 39 | return array.getLast(); 40 | } 41 | 42 | @Override 43 | public String toString(){ 44 | StringBuilder res = new StringBuilder(); 45 | res.append("Stack: "); 46 | res.append('['); 47 | for(int i = 0 ; i < array.getSize() ; i ++){ 48 | res.append(array.get(i)); 49 | if(i != array.getSize() - 1) 50 | res.append(", "); 51 | } 52 | res.append("] top"); 53 | return res.toString(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /04-Linked-List/07-Implement-Queue-in-LinkedList/src/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.Random; 2 | 3 | public class Main { 4 | 5 | // 测试使用q运行opCount个enqueueu和dequeue操作所需要的时间,单位:秒 6 | private static double testQueue(Queue q, int opCount){ 7 | 8 | long startTime = System.nanoTime(); 9 | 10 | Random random = new Random(); 11 | for(int i = 0 ; i < opCount ; i ++) 12 | q.enqueue(random.nextInt(Integer.MAX_VALUE)); 13 | for(int i = 0 ; i < opCount ; i ++) 14 | q.dequeue(); 15 | 16 | long endTime = System.nanoTime(); 17 | 18 | return (endTime - startTime) / 1000000000.0; 19 | } 20 | 21 | public static void main(String[] args) { 22 | 23 | int opCount = 100000; 24 | 25 | ArrayQueue arrayQueue = new ArrayQueue<>(); 26 | double time1 = testQueue(arrayQueue, opCount); 27 | System.out.println("ArrayQueue, time: " + time1 + " s"); 28 | 29 | LoopQueue loopQueue = new LoopQueue<>(); 30 | double time2 = testQueue(loopQueue, opCount); 31 | System.out.println("LoopQueue, time: " + time2 + " s"); 32 | 33 | LinkedListQueue linkedListQueue = new LinkedListQueue<>(); 34 | double time3 = testQueue(linkedListQueue, opCount); 35 | System.out.println("LinkedListQueue, time: " + time3 + " s"); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /06-Binary-Search-Tree/12-Remove-Elements-in-BST/src/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.Random; 3 | 4 | public class Main { 5 | 6 | // 打乱数组顺序 7 | private static void shuffle(Object[] arr){ 8 | 9 | for(int i = arr.length - 1 ; i >= 0 ; i --){ 10 | int pos = (int) (Math.random() * (i + 1)); 11 | Object t = arr[pos]; 12 | arr[pos] = arr[i]; 13 | arr[i] = t; 14 | } 15 | } 16 | 17 | public static void main(String[] args) { 18 | 19 | BST bst = new BST<>(); 20 | Random random = new Random(); 21 | 22 | int n = 10000; 23 | 24 | for(int i = 0 ; i < n ; i ++) 25 | bst.add(random.nextInt(n)); 26 | 27 | // 注意, 由于随机生成的数据有重复, 所以bst中的数据数量大概率是小于n的 28 | 29 | // order数组中存放[0...n)的所有元素 30 | Integer[] order = new Integer[n]; 31 | for( int i = 0 ; i < n ; i ++ ) 32 | order[i] = i; 33 | // 打乱order数组的顺序 34 | shuffle(order); 35 | 36 | // 乱序删除[0...n)范围里的所有元素 37 | for( int i = 0 ; i < n ; i ++ ) 38 | if(bst.contains(order[i])){ 39 | bst.remove(order[i]); 40 | System.out.println("After remove " + order[i] + ", size = " + bst.size() ); 41 | } 42 | 43 | // 最终整个二分搜索树应该为空 44 | System.out.println(bst.size()); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /14-Hash-Table/03-Hash-Function-in-Java/src/Student.java: -------------------------------------------------------------------------------- 1 | public class Student { 2 | 3 | int grade; 4 | int cls; 5 | String firstName; 6 | String lastName; 7 | 8 | Student(int grade, int cls, String firstName, String lastName){ 9 | this.grade = grade; 10 | this.cls = cls; 11 | this.firstName = firstName; 12 | this.lastName = lastName; 13 | } 14 | 15 | @Override 16 | public int hashCode(){ 17 | 18 | int B = 31; 19 | int hash = 0; 20 | hash = hash * B + ((Integer)grade).hashCode(); 21 | hash = hash * B + ((Integer)cls).hashCode(); 22 | hash = hash * B + firstName.toLowerCase().hashCode(); 23 | hash = hash * B + lastName.toLowerCase().hashCode(); 24 | return hash; 25 | } 26 | 27 | @Override 28 | public boolean equals(Object o){ 29 | 30 | if(this == o) 31 | return true; 32 | 33 | if(o == null) 34 | return false; 35 | 36 | if(getClass() != o.getClass()) 37 | return false; 38 | 39 | Student another = (Student)o; 40 | return this.grade == another.grade && 41 | this.cls == another.cls && 42 | this.firstName.toLowerCase().equals(another.firstName.toLowerCase()) && 43 | this.lastName.toLowerCase().equals(another.lastName.toLowerCase()); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /06-Binary-Search-Tree/11-Remove-Min-and-Max-in-BST/src/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.Random; 3 | 4 | public class Main { 5 | 6 | public static void main(String[] args) { 7 | 8 | BST bst = new BST<>(); 9 | Random random = new Random(); 10 | 11 | int n = 1000; 12 | 13 | // test removeMin 14 | for(int i = 0 ; i < n ; i ++) 15 | bst.add(random.nextInt(10000)); 16 | 17 | ArrayList nums = new ArrayList<>(); 18 | while(!bst.isEmpty()) 19 | nums.add(bst.removeMin()); 20 | 21 | System.out.println(nums); 22 | for(int i = 1 ; i < nums.size() ; i ++) 23 | if(nums.get(i - 1) > nums.get(i)) 24 | throw new IllegalArgumentException("Error!"); 25 | System.out.println("removeMin test completed."); 26 | 27 | 28 | // test removeMax 29 | for(int i = 0 ; i < n ; i ++) 30 | bst.add(random.nextInt(10000)); 31 | 32 | nums = new ArrayList<>(); 33 | while(!bst.isEmpty()) 34 | nums.add(bst.removeMax()); 35 | 36 | System.out.println(nums); 37 | for(int i = 1 ; i < nums.size() ; i ++) 38 | if(nums.get(i - 1) < nums.get(i)) 39 | throw new IllegalArgumentException("Error!"); 40 | System.out.println("removeMax test completed."); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /06-Binary-Search-Tree/Optional-03-Binary-Tree-Classic-Nonrecursive-Traversal/Postorder/src/Solution5.java: -------------------------------------------------------------------------------- 1 | /// Source : https://leetcode.com/problems/binary-tree-postorder-traversal/description/ 2 | /// Author : liuyubobobo 3 | /// Time : 2018-05-31 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.Stack; 8 | 9 | // Classic Non-Recursive 10 | // Using a pre pointer to record the last visted node 11 | // 12 | // Time Complexity: O(n) 13 | // Space Complexity: O(h) 14 | public class Solution5 { 15 | 16 | public List postorderTraversal(TreeNode root) { 17 | 18 | ArrayList res = new ArrayList(); 19 | if(root == null) 20 | return res; 21 | 22 | Stack stack = new Stack<>(); 23 | TreeNode pre = null; 24 | TreeNode cur = root; 25 | 26 | while(cur != null || !stack.empty()){ 27 | 28 | while(cur != null){ 29 | stack.push(cur); 30 | cur = cur.left; 31 | } 32 | 33 | cur = stack.pop(); 34 | if(cur.right == null || pre == cur.right){ 35 | res.add(cur.val); 36 | pre = cur; 37 | cur = null; 38 | } 39 | else{ 40 | stack.push(cur); 41 | cur = cur.right; 42 | } 43 | } 44 | return res; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /08-Heap-and-Priority-Queue/03-Add-and-Sift-Up-in-Heap/src/MaxHeap.java: -------------------------------------------------------------------------------- 1 | public class MaxHeap> { 2 | 3 | private Array data; 4 | 5 | public MaxHeap(int capacity){ 6 | data = new Array<>(capacity); 7 | } 8 | 9 | public MaxHeap(){ 10 | data = new Array<>(); 11 | } 12 | 13 | // 返回堆中的元素个数 14 | public int size(){ 15 | return data.getSize(); 16 | } 17 | 18 | // 返回一个布尔值, 表示堆中是否为空 19 | public boolean isEmpty(){ 20 | return data.isEmpty(); 21 | } 22 | 23 | // 返回完全二叉树的数组表示中,一个索引所表示的元素的父亲节点的索引 24 | private int parent(int index){ 25 | if(index == 0) 26 | throw new IllegalArgumentException("index-0 doesn't have parent."); 27 | return (index - 1) / 2; 28 | } 29 | 30 | // 返回完全二叉树的数组表示中,一个索引所表示的元素的左孩子节点的索引 31 | private int leftChild(int index){ 32 | return index * 2 + 1; 33 | } 34 | 35 | // 返回完全二叉树的数组表示中,一个索引所表示的元素的右孩子节点的索引 36 | private int rightChild(int index){ 37 | return index * 2 + 2; 38 | } 39 | 40 | // 向堆中添加元素 41 | public void add(E e){ 42 | data.addLast(e); 43 | siftUp(data.getSize() - 1); 44 | } 45 | 46 | private void siftUp(int k){ 47 | 48 | while(k > 0 && data.get(parent(k)).compareTo(data.get(k)) < 0 ){ 49 | data.swap(k, parent(k)); 50 | k = parent(k); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /06-Binary-Search-Tree/Optional-05-Binary-Tree-Morris-Traversal/src/PreorderSolution.java: -------------------------------------------------------------------------------- 1 | /// Source : https://leetcode.com/problems/binary-tree-preorder-traversal/description/ 2 | /// Author : liuyubobobo 3 | /// Time : 2018-05-29 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | // PreOrder Morris Traversal 9 | // Time Complexity: O(n), n is the node number in the tree 10 | // Space Complexity: O(1) 11 | public class PreorderSolution { 12 | 13 | public List preorderTraversal(TreeNode root) { 14 | 15 | ArrayList res = new ArrayList(); 16 | if(root == null) 17 | return res; 18 | 19 | TreeNode cur = root; 20 | while(cur != null){ 21 | if(cur.left == null){ 22 | res.add(cur.val); 23 | cur = cur.right; 24 | } 25 | else{ 26 | TreeNode prev = cur.left; 27 | while(prev.right != null && prev.right != cur) 28 | prev = prev.right; 29 | 30 | if(prev.right == null){ 31 | res.add(cur.val); 32 | prev.right = cur; 33 | cur = cur.left; 34 | } 35 | else{ 36 | prev.right = null; 37 | cur = cur.right; 38 | } 39 | } 40 | } 41 | 42 | return res; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /06-Binary-Search-Tree/Optional-05-Binary-Tree-Morris-Traversal/src/InorderSolution.java: -------------------------------------------------------------------------------- 1 | /// Source : https://leetcode.com/problems/binary-tree-inorder-traversal/solution/ 2 | /// Author : liuyubobobo 3 | /// Time : 2018-05-30 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.Stack; 8 | 9 | // Inorder Morris Traversal 10 | // Time Complexity: O(n), n is the node number in the tree 11 | // Space Complexity: O(1) 12 | public class InorderSolution { 13 | 14 | public List inorderTraversal(TreeNode root) { 15 | 16 | ArrayList res = new ArrayList(); 17 | if(root == null) 18 | return res; 19 | 20 | TreeNode cur = root; 21 | while(cur != null){ 22 | 23 | if(cur.left == null){ 24 | res.add(cur.val); 25 | cur = cur.right; 26 | } 27 | else{ 28 | TreeNode prev = cur.left; 29 | while(prev.right != null && prev.right != cur) 30 | prev = prev.right; 31 | 32 | if(prev.right == null){ 33 | prev.right = cur; 34 | cur = cur.left; 35 | } 36 | else{ 37 | prev.right = null; 38 | res.add(cur.val); 39 | cur = cur.right; 40 | } 41 | } 42 | } 43 | return res; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /11-Union-Find/03-Quick-Union/src/UnionFind2.java: -------------------------------------------------------------------------------- 1 | // 我们的第二版Union-Find 2 | public class UnionFind2 implements UF { 3 | 4 | // 我们的第二版Union-Find, 使用一个数组构建一棵指向父节点的树 5 | // parent[i]表示第一个元素所指向的父节点 6 | private int[] parent; 7 | 8 | // 构造函数 9 | public UnionFind2(int size){ 10 | 11 | parent = new int[size]; 12 | 13 | // 初始化, 每一个parent[i]指向自己, 表示每一个元素自己自成一个集合 14 | for( int i = 0 ; i < size ; i ++ ) 15 | parent[i] = i; 16 | } 17 | 18 | @Override 19 | public int getSize(){ 20 | return parent.length; 21 | } 22 | 23 | // 查找过程, 查找元素p所对应的集合编号 24 | // O(h)复杂度, h为树的高度 25 | private int find(int p){ 26 | if(p < 0 || p >= parent.length) 27 | throw new IllegalArgumentException("p is out of bound."); 28 | 29 | // 不断去查询自己的父亲节点, 直到到达根节点 30 | // 根节点的特点: parent[p] == p 31 | while(p != parent[p]) 32 | p = parent[p]; 33 | return p; 34 | } 35 | 36 | // 查看元素p和元素q是否所属一个集合 37 | // O(h)复杂度, h为树的高度 38 | @Override 39 | public boolean isConnected( int p , int q ){ 40 | return find(p) == find(q); 41 | } 42 | 43 | // 合并元素p和元素q所属的集合 44 | // O(h)复杂度, h为树的高度 45 | @Override 46 | public void unionElements(int p, int q){ 47 | 48 | int pRoot = find(p); 49 | int qRoot = find(q); 50 | 51 | if( pRoot == qRoot ) 52 | return; 53 | 54 | parent[pRoot] = qRoot; 55 | } 56 | } -------------------------------------------------------------------------------- /11-Union-Find/06-Path-Compression/src/UnionFind2.java: -------------------------------------------------------------------------------- 1 | // 我们的第二版Union-Find 2 | public class UnionFind2 implements UF { 3 | 4 | // 我们的第二版Union-Find, 使用一个数组构建一棵指向父节点的树 5 | // parent[i]表示第一个元素所指向的父节点 6 | private int[] parent; 7 | 8 | // 构造函数 9 | public UnionFind2(int size){ 10 | 11 | parent = new int[size]; 12 | 13 | // 初始化, 每一个parent[i]指向自己, 表示每一个元素自己自成一个集合 14 | for( int i = 0 ; i < size ; i ++ ) 15 | parent[i] = i; 16 | } 17 | 18 | @Override 19 | public int getSize(){ 20 | return parent.length; 21 | } 22 | 23 | // 查找过程, 查找元素p所对应的集合编号 24 | // O(h)复杂度, h为树的高度 25 | private int find(int p){ 26 | if(p < 0 || p >= parent.length) 27 | throw new IllegalArgumentException("p is out of bound."); 28 | 29 | // 不断去查询自己的父亲节点, 直到到达根节点 30 | // 根节点的特点: parent[p] == p 31 | while(p != parent[p]) 32 | p = parent[p]; 33 | return p; 34 | } 35 | 36 | // 查看元素p和元素q是否所属一个集合 37 | // O(h)复杂度, h为树的高度 38 | @Override 39 | public boolean isConnected( int p , int q ){ 40 | return find(p) == find(q); 41 | } 42 | 43 | // 合并元素p和元素q所属的集合 44 | // O(h)复杂度, h为树的高度 45 | @Override 46 | public void unionElements(int p, int q){ 47 | 48 | int pRoot = find(p); 49 | int qRoot = find(q); 50 | 51 | if( pRoot == qRoot ) 52 | return; 53 | 54 | parent[pRoot] = qRoot; 55 | } 56 | } -------------------------------------------------------------------------------- /11-Union-Find/04-Optimized-by-Size/src/UnionFind2.java: -------------------------------------------------------------------------------- 1 | // 我们的第二版Union-Find 2 | public class UnionFind2 implements UF { 3 | 4 | // 我们的第二版Union-Find, 使用一个数组构建一棵指向父节点的树 5 | // parent[i]表示第一个元素所指向的父节点 6 | private int[] parent; 7 | 8 | // 构造函数 9 | public UnionFind2(int size){ 10 | 11 | parent = new int[size]; 12 | 13 | // 初始化, 每一个parent[i]指向自己, 表示每一个元素自己自成一个集合 14 | for( int i = 0 ; i < size ; i ++ ) 15 | parent[i] = i; 16 | } 17 | 18 | @Override 19 | public int getSize(){ 20 | return parent.length; 21 | } 22 | 23 | // 查找过程, 查找元素p所对应的集合编号 24 | // O(h)复杂度, h为树的高度 25 | private int find(int p){ 26 | if(p < 0 || p >= parent.length) 27 | throw new IllegalArgumentException("p is out of bound."); 28 | 29 | // 不断去查询自己的父亲节点, 直到到达根节点 30 | // 根节点的特点: parent[p] == p 31 | while(p != parent[p]) 32 | p = parent[p]; 33 | return p; 34 | } 35 | 36 | // 查看元素p和元素q是否所属一个集合 37 | // O(h)复杂度, h为树的高度 38 | @Override 39 | public boolean isConnected( int p , int q ){ 40 | return find(p) == find(q); 41 | } 42 | 43 | // 合并元素p和元素q所属的集合 44 | // O(h)复杂度, h为树的高度 45 | @Override 46 | public void unionElements(int p, int q){ 47 | 48 | int pRoot = find(p); 49 | int qRoot = find(q); 50 | 51 | if( pRoot == qRoot ) 52 | return; 53 | 54 | parent[pRoot] = qRoot; 55 | } 56 | } -------------------------------------------------------------------------------- /11-Union-Find/05-Optimized-by-Rank/src/UnionFind2.java: -------------------------------------------------------------------------------- 1 | // 我们的第二版Union-Find 2 | public class UnionFind2 implements UF { 3 | 4 | // 我们的第二版Union-Find, 使用一个数组构建一棵指向父节点的树 5 | // parent[i]表示第一个元素所指向的父节点 6 | private int[] parent; 7 | 8 | // 构造函数 9 | public UnionFind2(int size){ 10 | 11 | parent = new int[size]; 12 | 13 | // 初始化, 每一个parent[i]指向自己, 表示每一个元素自己自成一个集合 14 | for( int i = 0 ; i < size ; i ++ ) 15 | parent[i] = i; 16 | } 17 | 18 | @Override 19 | public int getSize(){ 20 | return parent.length; 21 | } 22 | 23 | // 查找过程, 查找元素p所对应的集合编号 24 | // O(h)复杂度, h为树的高度 25 | private int find(int p){ 26 | if(p < 0 || p >= parent.length) 27 | throw new IllegalArgumentException("p is out of bound."); 28 | 29 | // 不断去查询自己的父亲节点, 直到到达根节点 30 | // 根节点的特点: parent[p] == p 31 | while(p != parent[p]) 32 | p = parent[p]; 33 | return p; 34 | } 35 | 36 | // 查看元素p和元素q是否所属一个集合 37 | // O(h)复杂度, h为树的高度 38 | @Override 39 | public boolean isConnected( int p , int q ){ 40 | return find(p) == find(q); 41 | } 42 | 43 | // 合并元素p和元素q所属的集合 44 | // O(h)复杂度, h为树的高度 45 | @Override 46 | public void unionElements(int p, int q){ 47 | 48 | int pRoot = find(p); 49 | int qRoot = find(q); 50 | 51 | if( pRoot == qRoot ) 52 | return; 53 | 54 | parent[pRoot] = qRoot; 55 | } 56 | } -------------------------------------------------------------------------------- /11-Union-Find/07-More-about-Union-Find/src/UnionFind2.java: -------------------------------------------------------------------------------- 1 | // 我们的第二版Union-Find 2 | public class UnionFind2 implements UF { 3 | 4 | // 我们的第二版Union-Find, 使用一个数组构建一棵指向父节点的树 5 | // parent[i]表示第一个元素所指向的父节点 6 | private int[] parent; 7 | 8 | // 构造函数 9 | public UnionFind2(int size){ 10 | 11 | parent = new int[size]; 12 | 13 | // 初始化, 每一个parent[i]指向自己, 表示每一个元素自己自成一个集合 14 | for( int i = 0 ; i < size ; i ++ ) 15 | parent[i] = i; 16 | } 17 | 18 | @Override 19 | public int getSize(){ 20 | return parent.length; 21 | } 22 | 23 | // 查找过程, 查找元素p所对应的集合编号 24 | // O(h)复杂度, h为树的高度 25 | private int find(int p){ 26 | if(p < 0 || p >= parent.length) 27 | throw new IllegalArgumentException("p is out of bound."); 28 | 29 | // 不断去查询自己的父亲节点, 直到到达根节点 30 | // 根节点的特点: parent[p] == p 31 | while(p != parent[p]) 32 | p = parent[p]; 33 | return p; 34 | } 35 | 36 | // 查看元素p和元素q是否所属一个集合 37 | // O(h)复杂度, h为树的高度 38 | @Override 39 | public boolean isConnected( int p , int q ){ 40 | return find(p) == find(q); 41 | } 42 | 43 | // 合并元素p和元素q所属的集合 44 | // O(h)复杂度, h为树的高度 45 | @Override 46 | public void unionElements(int p, int q){ 47 | 48 | int pRoot = find(p); 49 | int qRoot = find(q); 50 | 51 | if( pRoot == qRoot ) 52 | return; 53 | 54 | parent[pRoot] = qRoot; 55 | } 56 | } -------------------------------------------------------------------------------- /10-Trie/03-Searching-in-Trie/src/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class Main { 4 | 5 | public static void main(String[] args) { 6 | 7 | System.out.println("Pride and Prejudice"); 8 | 9 | ArrayList words = new ArrayList<>(); 10 | if(FileOperation.readFile("pride-and-prejudice.txt", words)){ 11 | 12 | long startTime = System.nanoTime(); 13 | 14 | BSTSet set = new BSTSet<>(); 15 | for(String word: words) 16 | set.add(word); 17 | 18 | for(String word: words) 19 | set.contains(word); 20 | 21 | long endTime = System.nanoTime(); 22 | 23 | double time = (endTime - startTime) / 1000000000.0; 24 | 25 | System.out.println("Total different words: " + set.getSize()); 26 | System.out.println("BSTSet: " + time + " s"); 27 | 28 | // --- 29 | 30 | startTime = System.nanoTime(); 31 | 32 | Trie trie = new Trie(); 33 | for(String word: words) 34 | trie.add(word); 35 | 36 | for(String word: words) 37 | trie.contains(word); 38 | 39 | endTime = System.nanoTime(); 40 | 41 | time = (endTime - startTime) / 1000000000.0; 42 | 43 | System.out.println("Total different words: " + trie.getSize()); 44 | System.out.println("Trie: " + time + " s"); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /10-Trie/04-Prefix-in-Trie/src/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class Main { 4 | 5 | public static void main(String[] args) { 6 | 7 | System.out.println("Pride and Prejudice"); 8 | 9 | ArrayList words = new ArrayList<>(); 10 | if(FileOperation.readFile("pride-and-prejudice.txt", words)){ 11 | 12 | long startTime = System.nanoTime(); 13 | 14 | BSTSet set = new BSTSet<>(); 15 | for(String word: words) 16 | set.add(word); 17 | 18 | for(String word: words) 19 | set.contains(word); 20 | 21 | long endTime = System.nanoTime(); 22 | 23 | double time = (endTime - startTime) / 1000000000.0; 24 | 25 | System.out.println("Total different words: " + set.getSize()); 26 | System.out.println("BSTSet: " + time + " s"); 27 | 28 | // --- 29 | 30 | startTime = System.nanoTime(); 31 | 32 | Trie trie = new Trie(); 33 | for(String word: words) 34 | trie.add(word); 35 | 36 | for(String word: words) 37 | trie.contains(word); 38 | 39 | endTime = System.nanoTime(); 40 | 41 | time = (endTime - startTime) / 1000000000.0; 42 | 43 | System.out.println("Total different words: " + trie.getSize()); 44 | System.out.println("Trie: " + time + " s"); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /11-Union-Find/05-Optimized-by-Rank/src/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.Random; 2 | 3 | public class Main { 4 | 5 | private static double testUF(UF uf, int m){ 6 | 7 | int size = uf.getSize(); 8 | Random random = new Random(); 9 | 10 | long startTime = System.nanoTime(); 11 | 12 | 13 | for(int i = 0 ; i < m ; i ++){ 14 | int a = random.nextInt(size); 15 | int b = random.nextInt(size); 16 | uf.unionElements(a, b); 17 | } 18 | 19 | for(int i = 0 ; i < m ; i ++){ 20 | int a = random.nextInt(size); 21 | int b = random.nextInt(size); 22 | uf.isConnected(a, b); 23 | } 24 | 25 | long endTime = System.nanoTime(); 26 | 27 | return (endTime - startTime) / 1000000000.0; 28 | } 29 | 30 | public static void main(String[] args) { 31 | 32 | int size = 10000000; 33 | int m = 10000000; 34 | 35 | // UnionFind1 uf1 = new UnionFind1(size); 36 | // System.out.println("UnionFind1 : " + testUF(uf1, m) + " s"); 37 | // 38 | // UnionFind2 uf2 = new UnionFind2(size); 39 | // System.out.println("UnionFind2 : " + testUF(uf2, m) + " s"); 40 | 41 | UnionFind3 uf3 = new UnionFind3(size); 42 | System.out.println("UnionFind3 : " + testUF(uf3, m) + " s"); 43 | 44 | UnionFind4 uf4 = new UnionFind4(size); 45 | System.out.println("UnionFind4 : " + testUF(uf4, m) + " s"); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /06-Binary-Search-Tree/Optional-03-Binary-Tree-Classic-Nonrecursive-Traversal/Postorder/src/Solution6.java: -------------------------------------------------------------------------------- 1 | /// Source : https://leetcode.com/problems/binary-tree-postorder-traversal/description/ 2 | /// Author : liuyubobobo 3 | /// Time : 2018-05-31 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.Stack; 8 | 9 | // Classic Non-Recursive 10 | // Using a pre pointer to record the last visted node 11 | // 12 | // Time Complexity: O(n) 13 | // Space Complexity: O(h) 14 | public class Solution6 { 15 | 16 | public List postorderTraversal(TreeNode root) { 17 | 18 | ArrayList res = new ArrayList(); 19 | if(root == null) 20 | return res; 21 | 22 | Stack stack = new Stack<>(); 23 | TreeNode pre = null; 24 | TreeNode cur = root; 25 | 26 | while(cur != null || !stack.empty()){ 27 | 28 | if(cur != null){ 29 | stack.push(cur); 30 | cur = cur.left; 31 | } 32 | else{ 33 | cur = stack.pop(); 34 | if(cur.right == null || pre == cur.right){ 35 | res.add(cur.val); 36 | pre = cur; 37 | cur = null; 38 | } 39 | else{ 40 | stack.push(cur); 41 | cur = cur.right; 42 | } 43 | } 44 | } 45 | return res; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /11-Union-Find/04-Optimized-by-Size/src/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.Random; 2 | 3 | public class Main { 4 | 5 | private static double testUF(UF uf, int m){ 6 | 7 | int size = uf.getSize(); 8 | Random random = new Random(); 9 | 10 | long startTime = System.nanoTime(); 11 | 12 | 13 | for(int i = 0 ; i < m ; i ++){ 14 | int a = random.nextInt(size); 15 | int b = random.nextInt(size); 16 | uf.unionElements(a, b); 17 | } 18 | 19 | for(int i = 0 ; i < m ; i ++){ 20 | int a = random.nextInt(size); 21 | int b = random.nextInt(size); 22 | uf.isConnected(a, b); 23 | } 24 | 25 | long endTime = System.nanoTime(); 26 | 27 | return (endTime - startTime) / 1000000000.0; 28 | } 29 | 30 | public static void main(String[] args) { 31 | 32 | // UnionFind1 慢于 UnionFind2 33 | // int size = 100000; 34 | // int m = 10000; 35 | 36 | // UnionFind2 慢于 UnionFind1, 但UnionFind3最快 37 | int size = 100000; 38 | int m = 100000; 39 | 40 | UnionFind1 uf1 = new UnionFind1(size); 41 | System.out.println("UnionFind1 : " + testUF(uf1, m) + " s"); 42 | 43 | UnionFind2 uf2 = new UnionFind2(size); 44 | System.out.println("UnionFind2 : " + testUF(uf2, m) + " s"); 45 | 46 | UnionFind3 uf3 = new UnionFind3(size); 47 | System.out.println("UnionFind3 : " + testUF(uf3, m) + " s"); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /10-Trie/08-Trie-Using-HashMap-and-Array/src/Trie3.java: -------------------------------------------------------------------------------- 1 | public class Trie3 { 2 | 3 | private class Node{ 4 | 5 | public boolean isWord; 6 | public Node[] next; 7 | 8 | public Node(boolean isWord){ 9 | this.isWord = isWord; 10 | next = new Node[26]; 11 | } 12 | 13 | public Node(){ 14 | this(false); 15 | } 16 | } 17 | 18 | private Node root; 19 | private int size; 20 | 21 | public Trie3(){ 22 | root = new Node(); 23 | size = 0; 24 | } 25 | 26 | // 获得Trie中存储的单词数量 27 | public int getSize(){ 28 | return size; 29 | } 30 | 31 | // 向Trie中添加一个新的单词word 32 | public void add(String word){ 33 | 34 | Node cur = root; 35 | for(int i = 0 ; i < word.length() ; i ++){ 36 | char c = word.charAt(i); 37 | if(cur.next[c-'a'] == null) 38 | cur.next[c-'a'] = new Node(); 39 | cur = cur.next[c-'a']; 40 | } 41 | 42 | if(!cur.isWord){ 43 | cur.isWord = true; 44 | size ++; 45 | } 46 | } 47 | 48 | // 查询单词word是否在Trie中 49 | public boolean contains(String word){ 50 | 51 | Node cur = root; 52 | for(int i = 0 ; i < word.length() ; i ++){ 53 | char c = word.charAt(i); 54 | if(cur.next[c-'a'] == null) 55 | return false; 56 | cur = cur.next[c-'a']; 57 | } 58 | return cur.isWord; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /06-Binary-Search-Tree/Optional-03-Binary-Tree-Classic-Nonrecursive-Traversal/Postorder/src/Solution4.java: -------------------------------------------------------------------------------- 1 | /// Source : https://leetcode.com/problems/binary-tree-postorder-traversal/description/ 2 | /// Author : liuyubobobo 3 | /// Time : 2018-05-31 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.Stack; 8 | 9 | // Non-Recursive 10 | // Using a pre pointer to record the last visted node 11 | // 12 | // Time Complexity: O(n) 13 | // Space Complexity: O(h) 14 | public class Solution4 { 15 | 16 | public List postorderTraversal(TreeNode root) { 17 | 18 | ArrayList res = new ArrayList(); 19 | if(root == null) 20 | return res; 21 | 22 | Stack stack = new Stack<>(); 23 | TreeNode pre = null; 24 | 25 | stack.push(root); 26 | while(!stack.empty()){ 27 | 28 | TreeNode cur = stack.pop(); 29 | if((cur.left == null && cur.right == null) || 30 | (pre != null && pre == cur.left && cur.right == null) || 31 | (pre != null && pre == cur.right)){ 32 | res.add(cur.val); 33 | pre = cur; 34 | } 35 | else{ 36 | stack.push(cur); 37 | if(cur.right != null) 38 | stack.push(cur.right); 39 | if(cur.left != null) 40 | stack.push(cur.left); 41 | } 42 | } 43 | return res; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /10-Trie/06-Trie-and-Map/src/MapSum.java: -------------------------------------------------------------------------------- 1 | import java.util.TreeMap; 2 | 3 | public class MapSum { 4 | 5 | private class Node{ 6 | 7 | public int value; 8 | public TreeMap next; 9 | 10 | public Node(int value){ 11 | this.value = value; 12 | next = new TreeMap<>(); 13 | } 14 | 15 | public Node(){ 16 | this(0); 17 | } 18 | } 19 | 20 | private Node root; 21 | 22 | /** Initialize your data structure here. */ 23 | public MapSum() { 24 | 25 | root = new Node(); 26 | } 27 | 28 | public void insert(String key, int val) { 29 | 30 | Node cur = root; 31 | for(int i = 0 ; i < key.length() ; i ++){ 32 | char c = key.charAt(i); 33 | if(cur.next.get(c) == null) 34 | cur.next.put(c, new Node()); 35 | cur = cur.next.get(c); 36 | } 37 | cur.value = val; 38 | } 39 | 40 | public int sum(String prefix) { 41 | 42 | Node cur = root; 43 | for(int i = 0 ; i < prefix.length() ; i ++){ 44 | char c = prefix.charAt(i); 45 | if(cur.next.get(c) == null) 46 | return 0; 47 | cur = cur.next.get(c); 48 | } 49 | 50 | return sum(cur); 51 | } 52 | 53 | private int sum(Node node){ 54 | 55 | int res = node.value; 56 | for(char c: node.next.keySet()) 57 | res += sum(node.next.get(c)); 58 | return res; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /06-Binary-Search-Tree/03-Add-Elements-in-BST/src/BST.java: -------------------------------------------------------------------------------- 1 | public class BST> { 2 | 3 | private class Node { 4 | public E e; 5 | public Node left, right; 6 | 7 | public Node(E e) { 8 | this.e = e; 9 | left = null; 10 | right = null; 11 | } 12 | } 13 | 14 | private Node root; 15 | private int size; 16 | 17 | public BST(){ 18 | root = null; 19 | size = 0; 20 | } 21 | 22 | public int size(){ 23 | return size; 24 | } 25 | 26 | public boolean isEmpty(){ 27 | return size == 0; 28 | } 29 | 30 | // 向二分搜索树中添加新的元素e 31 | public void add(E e){ 32 | 33 | if(root == null){ 34 | root = new Node(e); 35 | size ++; 36 | } 37 | else 38 | add(root, e); 39 | } 40 | 41 | // 向以node为根的二分搜索树中插入元素e,递归算法 42 | private void add(Node node, E e){ 43 | if(e.equals(node.e)) 44 | return; 45 | else if(e.compareTo(node.e) < 0 && node.left == null){ 46 | node.left = new Node(e); 47 | size ++; 48 | return; 49 | } 50 | else if(e.compareTo(node.e) > 0 && node.right == null){ 51 | node.right = new Node(e); 52 | size ++; 53 | return; 54 | } 55 | 56 | if(e.compareTo(node.e) < 0) 57 | add(node.left, e); 58 | else //e.compareTo(node.e) > 0 59 | add(node.right, e); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /08-Heap-and-Priority-Queue/08-Priority-Queue-in-Java/src/Solution5.java: -------------------------------------------------------------------------------- 1 | /// 347. Top K Frequent Elements 2 | /// https://leetcode.com/problems/top-k-frequent-elements/description/ 3 | 4 | import java.util.*; 5 | 6 | public class Solution5 { 7 | 8 | public List topKFrequent(int[] nums, int k) { 9 | 10 | TreeMap map = new TreeMap<>(); 11 | for(int num: nums){ 12 | if(map.containsKey(num)) 13 | map.put(num, map.get(num) + 1); 14 | else 15 | map.put(num, 1); 16 | } 17 | 18 | PriorityQueue pq = new PriorityQueue<>( 19 | (a, b) -> map.get(a) - map.get(b) 20 | ); 21 | for(int key: map.keySet()){ 22 | if(pq.size() < k) 23 | pq.add(key); 24 | else if(map.get(key) > map.get(pq.peek())){ 25 | pq.remove(); 26 | pq.add(key); 27 | } 28 | } 29 | 30 | LinkedList res = new LinkedList<>(); 31 | while(!pq.isEmpty()) 32 | res.add(pq.remove()); 33 | return res; 34 | } 35 | 36 | private static void printList(List nums){ 37 | for(Integer num: nums) 38 | System.out.print(num + " "); 39 | System.out.println(); 40 | } 41 | 42 | public static void main(String[] args) { 43 | 44 | int[] nums = {1, 1, 1, 2, 2, 3}; 45 | int k = 2; 46 | printList((new Solution()).topKFrequent(nums, k)); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /12-AVL-Tree/08-Map-and-Set-in-AVL-Tree/src/TestSetMain.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class TestSetMain { 4 | 5 | private static double testSet(Set set, String filename){ 6 | 7 | long startTime = System.nanoTime(); 8 | 9 | System.out.println(filename); 10 | ArrayList words = new ArrayList<>(); 11 | if(FileOperation.readFile(filename, words)) { 12 | System.out.println("Total words: " + words.size()); 13 | 14 | for (String word : words) 15 | set.add(word); 16 | System.out.println("Total different words: " + set.getSize()); 17 | } 18 | 19 | long endTime = System.nanoTime(); 20 | 21 | return (endTime - startTime) / 1000000000.0; 22 | } 23 | 24 | public static void main(String[] args) { 25 | 26 | String filename = "pride-and-prejudice.txt"; 27 | 28 | BSTSet bstSet = new BSTSet<>(); 29 | double time1 = testSet(bstSet, filename); 30 | System.out.println("BST Set: " + time1 + " s"); 31 | 32 | System.out.println(); 33 | 34 | LinkedListSet linkedListSet = new LinkedListSet<>(); 35 | double time2 = testSet(linkedListSet, filename); 36 | System.out.println("Linked List Set: " + time2 + " s"); 37 | 38 | System.out.println(); 39 | 40 | AVLSet avlSet = new AVLSet<>(); 41 | double time3 = testSet(avlSet, filename); 42 | System.out.println("AVL Set: " + time3 + " s"); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /10-Trie/03-Searching-in-Trie/src/Trie.java: -------------------------------------------------------------------------------- 1 | import java.util.TreeMap; 2 | 3 | public class Trie { 4 | 5 | private class Node{ 6 | 7 | public boolean isWord; 8 | public TreeMap next; 9 | 10 | public Node(boolean isWord){ 11 | this.isWord = isWord; 12 | next = new TreeMap<>(); 13 | } 14 | 15 | public Node(){ 16 | this(false); 17 | } 18 | } 19 | 20 | private Node root; 21 | private int size; 22 | 23 | public Trie(){ 24 | root = new Node(); 25 | size = 0; 26 | } 27 | 28 | // 获得Trie中存储的单词数量 29 | public int getSize(){ 30 | return size; 31 | } 32 | 33 | // 向Trie中添加一个新的单词word 34 | public void add(String word){ 35 | 36 | Node cur = root; 37 | for(int i = 0 ; i < word.length() ; i ++){ 38 | char c = word.charAt(i); 39 | if(cur.next.get(c) == null) 40 | cur.next.put(c, new Node()); 41 | cur = cur.next.get(c); 42 | } 43 | 44 | if(!cur.isWord){ 45 | cur.isWord = true; 46 | size ++; 47 | } 48 | } 49 | 50 | // 查询单词word是否在Trie中 51 | public boolean contains(String word){ 52 | 53 | Node cur = root; 54 | for(int i = 0 ; i < word.length() ; i ++){ 55 | char c = word.charAt(i); 56 | if(cur.next.get(c) == null) 57 | return false; 58 | cur = cur.next.get(c); 59 | } 60 | return cur.isWord; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /08-Heap-and-Priority-Queue/06-Priority-Queue/src/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.Random; 2 | 3 | public class Main { 4 | 5 | private static double testHeap(Integer[] testData, boolean isHeapify){ 6 | 7 | long startTime = System.nanoTime(); 8 | 9 | MaxHeap maxHeap; 10 | if(isHeapify) 11 | maxHeap = new MaxHeap<>(testData); 12 | else{ 13 | maxHeap = new MaxHeap<>(); 14 | for(int num: testData) 15 | maxHeap.add(num); 16 | } 17 | 18 | int[] arr = new int[testData.length]; 19 | for(int i = 0 ; i < testData.length ; i ++) 20 | arr[i] = maxHeap.extractMax(); 21 | 22 | for(int i = 1 ; i < testData.length ; i ++) 23 | if(arr[i-1] < arr[i]) 24 | throw new IllegalArgumentException("Error"); 25 | System.out.println("Test MaxHeap completed."); 26 | 27 | long endTime = System.nanoTime(); 28 | 29 | return (endTime - startTime) / 1000000000.0; 30 | } 31 | 32 | public static void main(String[] args) { 33 | 34 | int n = 1000000; 35 | 36 | Random random = new Random(); 37 | Integer[] testData = new Integer[n]; 38 | for(int i = 0 ; i < n ; i ++) 39 | testData[i] = random.nextInt(Integer.MAX_VALUE); 40 | 41 | double time1 = testHeap(testData, false); 42 | System.out.println("Without heapify: " + time1 + " s"); 43 | 44 | double time2 = testHeap(testData, true); 45 | System.out.println("With heapify: " + time2 + " s"); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /10-Trie/08-Trie-Using-HashMap-and-Array/src/Trie.java: -------------------------------------------------------------------------------- 1 | import java.util.TreeMap; 2 | 3 | /// 使用TreeMap的Trie 4 | public class Trie { 5 | 6 | private class Node{ 7 | 8 | public boolean isWord; 9 | public TreeMap next; 10 | 11 | public Node(boolean isWord){ 12 | this.isWord = isWord; 13 | next = new TreeMap<>(); 14 | } 15 | 16 | public Node(){ 17 | this(false); 18 | } 19 | } 20 | 21 | private Node root; 22 | private int size; 23 | 24 | public Trie(){ 25 | root = new Node(); 26 | size = 0; 27 | } 28 | 29 | // 获得Trie中存储的单词数量 30 | public int getSize(){ 31 | return size; 32 | } 33 | 34 | // 向Trie中添加一个新的单词word 35 | public void add(String word){ 36 | 37 | Node cur = root; 38 | for(int i = 0 ; i < word.length() ; i ++){ 39 | char c = word.charAt(i); 40 | if(cur.next.get(c) == null) 41 | cur.next.put(c, new Node()); 42 | cur = cur.next.get(c); 43 | } 44 | 45 | if(!cur.isWord){ 46 | cur.isWord = true; 47 | size ++; 48 | } 49 | } 50 | 51 | // 查询单词word是否在Trie中 52 | public boolean contains(String word){ 53 | 54 | Node cur = root; 55 | for(int i = 0 ; i < word.length() ; i ++){ 56 | char c = word.charAt(i); 57 | if(cur.next.get(c) == null) 58 | return false; 59 | cur = cur.next.get(c); 60 | } 61 | return cur.isWord; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /10-Trie/08-Trie-Using-HashMap-and-Array/src/Trie2.java: -------------------------------------------------------------------------------- 1 | import java.util.HashMap; 2 | 3 | // 使用HashMap的Trie 4 | public class Trie2 { 5 | 6 | private class Node{ 7 | 8 | public boolean isWord; 9 | public HashMap next; 10 | 11 | public Node(boolean isWord){ 12 | this.isWord = isWord; 13 | next = new HashMap<>(); 14 | } 15 | 16 | public Node(){ 17 | this(false); 18 | } 19 | } 20 | 21 | private Node root; 22 | private int size; 23 | 24 | public Trie2(){ 25 | root = new Node(); 26 | size = 0; 27 | } 28 | 29 | // 获得Trie中存储的单词数量 30 | public int getSize(){ 31 | return size; 32 | } 33 | 34 | // 向Trie中添加一个新的单词word 35 | public void add(String word){ 36 | 37 | Node cur = root; 38 | for(int i = 0 ; i < word.length() ; i ++){ 39 | char c = word.charAt(i); 40 | if(cur.next.get(c) == null) 41 | cur.next.put(c, new Node()); 42 | cur = cur.next.get(c); 43 | } 44 | 45 | if(!cur.isWord){ 46 | cur.isWord = true; 47 | size ++; 48 | } 49 | } 50 | 51 | // 查询单词word是否在Trie中 52 | public boolean contains(String word){ 53 | 54 | Node cur = root; 55 | for(int i = 0 ; i < word.length() ; i ++){ 56 | char c = word.charAt(i); 57 | if(cur.next.get(c) == null) 58 | return false; 59 | cur = cur.next.get(c); 60 | } 61 | return cur.isWord; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /05-Recursion/06-Debug-Recursive-Solution/src/Solution.java: -------------------------------------------------------------------------------- 1 | public class Solution { 2 | 3 | public ListNode removeElements(ListNode head, int val, int depth) { 4 | 5 | String depthString = generateDepthString(depth); 6 | 7 | System.out.print(depthString); 8 | System.out.println("Call: remove " + val + " in " + head); 9 | 10 | if(head == null){ 11 | System.out.print(depthString); 12 | System.out.println("Return: " + head); 13 | return head; 14 | } 15 | 16 | ListNode res = removeElements(head.next, val, depth + 1); 17 | System.out.print(depthString); 18 | System.out.println("After remove " + val + ": " + res); 19 | 20 | ListNode ret; 21 | if(head.val == val) 22 | ret = res; 23 | else{ 24 | head.next = res; 25 | ret = head; 26 | } 27 | System.out.print(depthString); 28 | System.out.println("Return: " + ret); 29 | 30 | return ret; 31 | } 32 | 33 | private String generateDepthString(int depth){ 34 | StringBuilder res = new StringBuilder(); 35 | for(int i = 0 ; i < depth ; i ++) 36 | res.append("--"); 37 | return res.toString(); 38 | } 39 | 40 | public static void main(String[] args) { 41 | 42 | int[] nums = {1, 2, 6, 3, 4, 5, 6}; 43 | ListNode head = new ListNode(nums); 44 | System.out.println(head); 45 | 46 | ListNode res = (new Solution()).removeElements(head, 6, 0); 47 | System.out.println(res); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /04-Linked-List/03-DummyHead-in-LinkedList/src/LinkedList.java: -------------------------------------------------------------------------------- 1 | public class LinkedList { 2 | 3 | private class Node{ 4 | public E e; 5 | public Node next; 6 | 7 | public Node(E e, Node next){ 8 | this.e = e; 9 | this.next = next; 10 | } 11 | 12 | public Node(E e){ 13 | this(e, null); 14 | } 15 | 16 | public Node(){ 17 | this(null, null); 18 | } 19 | 20 | @Override 21 | public String toString(){ 22 | return e.toString(); 23 | } 24 | } 25 | 26 | private Node dummyHead; 27 | private int size; 28 | 29 | public LinkedList(){ 30 | dummyHead = new Node(); 31 | size = 0; 32 | } 33 | 34 | // 获取链表中的元素个数 35 | public int getSize(){ 36 | return size; 37 | } 38 | 39 | // 返回链表是否为空 40 | public boolean isEmpty(){ 41 | return size == 0; 42 | } 43 | 44 | // 在链表的index(0-based)位置添加新的元素e 45 | // 在链表中不是一个常用的操作,练习用:) 46 | public void add(int index, E e){ 47 | 48 | if(index < 0 || index > size) 49 | throw new IllegalArgumentException("Add failed. Illegal index."); 50 | 51 | Node prev = dummyHead; 52 | for(int i = 0 ; i < index ; i ++) 53 | prev = prev.next; 54 | 55 | prev.next = new Node(e, prev.next); 56 | size ++; 57 | } 58 | 59 | // 在链表头添加新的元素e 60 | public void addFirst(E e){ 61 | add(0, e); 62 | } 63 | 64 | // 在链表末尾添加新的元素e 65 | public void addLast(E e){ 66 | add(size, e); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /02-Arrays/03-Add-Element-in-Array/src/Array.java: -------------------------------------------------------------------------------- 1 | 2 | public class Array { 3 | 4 | private int[] data; 5 | private int size; 6 | 7 | // 构造函数,传入数组的容量capacity构造Array 8 | public Array(int capacity){ 9 | data = new int[capacity]; 10 | size = 0; 11 | } 12 | 13 | // 无参数的构造函数,默认数组的容量capacity=10 14 | public Array(){ 15 | this(10); 16 | } 17 | 18 | // 获取数组的容量 19 | public int getCapacity(){ 20 | return data.length; 21 | } 22 | 23 | // 获取数组中的元素个数 24 | public int getSize(){ 25 | return size; 26 | } 27 | 28 | // 返回数组是否为空 29 | public boolean isEmpty(){ 30 | return size == 0; 31 | } 32 | 33 | // 向所有元素后添加一个新元素 34 | public void addLast(int e){ 35 | 36 | // if(size == data.length) 37 | // throw new IllegalArgumentException("AddLast failed. Array is full."); 38 | // 39 | // data[size] = e; 40 | // size ++; 41 | add(size, e); 42 | } 43 | 44 | // 在所有元素前添加一个新元素 45 | public void addFirst(int e){ 46 | add(0, e); 47 | } 48 | 49 | // 在index索引的位置插入一个新元素e 50 | public void add(int index, int e){ 51 | 52 | if(size == data.length) 53 | throw new IllegalArgumentException("Add failed. Array is full."); 54 | 55 | if(index < 0 || index > size) 56 | throw new IllegalArgumentException("Add failed. Require index >= 0 and index <= size."); 57 | 58 | for(int i = size - 1; i >= index ; i --) 59 | data[i + 1] = data[i]; 60 | 61 | data[index] = e; 62 | 63 | size ++; 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /11-Union-Find/06-Path-Compression/src/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.Random; 2 | 3 | public class Main { 4 | 5 | private static double testUF(UF uf, int m){ 6 | 7 | int size = uf.getSize(); 8 | Random random = new Random(); 9 | 10 | long startTime = System.nanoTime(); 11 | 12 | 13 | for(int i = 0 ; i < m ; i ++){ 14 | int a = random.nextInt(size); 15 | int b = random.nextInt(size); 16 | uf.unionElements(a, b); 17 | } 18 | 19 | for(int i = 0 ; i < m ; i ++){ 20 | int a = random.nextInt(size); 21 | int b = random.nextInt(size); 22 | uf.isConnected(a, b); 23 | } 24 | 25 | long endTime = System.nanoTime(); 26 | 27 | double time = (endTime - startTime) / 1000000000.0; 28 | return time; 29 | } 30 | 31 | public static void main(String[] args) { 32 | 33 | int size = 10000000; 34 | int m = 10000000; 35 | 36 | // UnionFind1 uf1 = new UnionFind1(size); 37 | // System.out.println("UnionFind1 : " + testUF(uf1, m) + " s"); 38 | // 39 | // UnionFind2 uf2 = new UnionFind2(size); 40 | // System.out.println("UnionFind2 : " + testUF(uf2, m) + " s"); 41 | 42 | UnionFind3 uf3 = new UnionFind3(size); 43 | System.out.println("UnionFind3 : " + testUF(uf3, m) + " s"); 44 | 45 | UnionFind4 uf4 = new UnionFind4(size); 46 | System.out.println("UnionFind4 : " + testUF(uf4, m) + " s"); 47 | 48 | UnionFind5 uf5 = new UnionFind5(size); 49 | System.out.println("UnionFind5 : " + testUF(uf5, m) + " s"); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /13-Red-Black-Tree/08-The-Performance-of-Red-Black-Tree/src/Main2.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.Random; 3 | 4 | public class Main2 { 5 | 6 | public static void main(String[] args) { 7 | 8 | // int n = 20000000; 9 | int n = 20000000; 10 | 11 | Random random = new Random(n); 12 | ArrayList testData = new ArrayList<>(n); 13 | for(int i = 0 ; i < n ; i ++) 14 | testData.add(random.nextInt(Integer.MAX_VALUE)); 15 | 16 | // Test BST 17 | long startTime = System.nanoTime(); 18 | 19 | BST bst = new BST<>(); 20 | for (Integer x: testData) 21 | bst.add(x, null); 22 | 23 | long endTime = System.nanoTime(); 24 | 25 | double time = (endTime - startTime) / 1000000000.0; 26 | System.out.println("BST: " + time + " s"); 27 | 28 | 29 | // Test AVL 30 | startTime = System.nanoTime(); 31 | 32 | AVLTree avl = new AVLTree<>(); 33 | for (Integer x: testData) 34 | avl.add(x, null); 35 | 36 | endTime = System.nanoTime(); 37 | 38 | time = (endTime - startTime) / 1000000000.0; 39 | System.out.println("AVL: " + time + " s"); 40 | 41 | 42 | // Test RBTree 43 | startTime = System.nanoTime(); 44 | 45 | RBTree rbt = new RBTree<>(); 46 | for (Integer x: testData) 47 | rbt.add(x, null); 48 | 49 | endTime = System.nanoTime(); 50 | 51 | time = (endTime - startTime) / 1000000000.0; 52 | System.out.println("RBTree: " + time + " s"); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /07-Set-and-Map/08-More-about-Map/src/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class Main { 4 | 5 | private static double testMap(Map map, String filename){ 6 | 7 | long startTime = System.nanoTime(); 8 | 9 | System.out.println(filename); 10 | ArrayList words = new ArrayList<>(); 11 | if(FileOperation.readFile(filename, words)) { 12 | System.out.println("Total words: " + words.size()); 13 | 14 | for (String word : words){ 15 | if(map.contains(word)) 16 | map.set(word, map.get(word) + 1); 17 | else 18 | map.add(word, 1); 19 | } 20 | 21 | System.out.println("Total different words: " + map.getSize()); 22 | System.out.println("Frequency of PRIDE: " + map.get("pride")); 23 | System.out.println("Frequency of PREJUDICE: " + map.get("prejudice")); 24 | } 25 | 26 | long endTime = System.nanoTime(); 27 | 28 | return (endTime - startTime) / 1000000000.0; 29 | } 30 | 31 | public static void main(String[] args) { 32 | 33 | String filename = "pride-and-prejudice.txt"; 34 | 35 | BSTMap bstMap = new BSTMap<>(); 36 | double time1 = testMap(bstMap, filename); 37 | System.out.println("BST Map: " + time1 + " s"); 38 | 39 | System.out.println(); 40 | 41 | LinkedListMap linkedListMap = new LinkedListMap<>(); 42 | double time2 = testMap(linkedListMap, filename); 43 | System.out.println("Linked List Map: " + time2 + " s"); 44 | 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /08-Heap-and-Priority-Queue/08-Priority-Queue-in-Java/src/Solution4.java: -------------------------------------------------------------------------------- 1 | /// 347. Top K Frequent Elements 2 | /// https://leetcode.com/problems/top-k-frequent-elements/description/ 3 | 4 | import java.util.*; 5 | 6 | public class Solution4 { 7 | 8 | public List topKFrequent(int[] nums, int k) { 9 | 10 | TreeMap map = new TreeMap<>(); 11 | for(int num: nums){ 12 | if(map.containsKey(num)) 13 | map.put(num, map.get(num) + 1); 14 | else 15 | map.put(num, 1); 16 | } 17 | 18 | PriorityQueue pq = new PriorityQueue<>(new Comparator() { 19 | @Override 20 | public int compare(Integer a, Integer b) { 21 | return map.get(a) - map.get(b); 22 | } 23 | }); 24 | for(int key: map.keySet()){ 25 | if(pq.size() < k) 26 | pq.add(key); 27 | else if(map.get(key) > map.get(pq.peek())){ 28 | pq.remove(); 29 | pq.add(key); 30 | } 31 | } 32 | 33 | LinkedList res = new LinkedList<>(); 34 | while(!pq.isEmpty()) 35 | res.add(pq.remove()); 36 | return res; 37 | } 38 | 39 | private static void printList(List nums){ 40 | for(Integer num: nums) 41 | System.out.print(num + " "); 42 | System.out.println(); 43 | } 44 | 45 | public static void main(String[] args) { 46 | 47 | int[] nums = {1, 1, 1, 2, 2, 3}; 48 | int k = 2; 49 | printList((new Solution()).topKFrequent(nums, k)); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /04-Linked-List/06-Implement-Stack-in-LinkedList/src/ArrayStack.java: -------------------------------------------------------------------------------- 1 | public class ArrayStack implements Stack { 2 | 3 | private Array array; 4 | 5 | public ArrayStack(int capacity){ 6 | array = new Array<>(capacity); 7 | } 8 | 9 | public ArrayStack(){ 10 | array = new Array<>(); 11 | } 12 | 13 | @Override 14 | public int getSize(){ 15 | return array.getSize(); 16 | } 17 | 18 | @Override 19 | public boolean isEmpty(){ 20 | return array.isEmpty(); 21 | } 22 | 23 | public int getCapacity(){ 24 | return array.getCapacity(); 25 | } 26 | 27 | @Override 28 | public void push(E e){ 29 | array.addLast(e); 30 | } 31 | 32 | @Override 33 | public E pop(){ 34 | return array.removeLast(); 35 | } 36 | 37 | @Override 38 | public E peek(){ 39 | return array.getLast(); 40 | } 41 | 42 | @Override 43 | public String toString(){ 44 | StringBuilder res = new StringBuilder(); 45 | res.append("Stack: "); 46 | res.append('['); 47 | for(int i = 0 ; i < array.getSize() ; i ++){ 48 | res.append(array.get(i)); 49 | if(i != array.getSize() - 1) 50 | res.append(", "); 51 | } 52 | res.append("] top"); 53 | return res.toString(); 54 | } 55 | 56 | public static void main(String[] args) { 57 | 58 | ArrayStack stack = new ArrayStack<>(); 59 | 60 | for(int i = 0 ; i < 5 ; i ++){ 61 | stack.push(i); 62 | System.out.println(stack); 63 | } 64 | 65 | stack.pop(); 66 | System.out.println(stack); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /08-Heap-and-Priority-Queue/05-Heapify-and-Replace-in-Heap/src/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.Arrays; 2 | import java.util.Random; 3 | 4 | public class Main { 5 | 6 | private static double testHeap(Integer[] testData, boolean isHeapify){ 7 | 8 | long startTime = System.nanoTime(); 9 | 10 | MaxHeap maxHeap; 11 | if(isHeapify) 12 | maxHeap = new MaxHeap<>(testData); 13 | else{ 14 | maxHeap = new MaxHeap<>(testData.length); 15 | for(int num: testData) 16 | maxHeap.add(num); 17 | } 18 | 19 | int[] arr = new int[testData.length]; 20 | for(int i = 0 ; i < testData.length ; i ++) 21 | arr[i] = maxHeap.extractMax(); 22 | 23 | for(int i = 1 ; i < testData.length ; i ++) 24 | if(arr[i-1] < arr[i]) 25 | throw new IllegalArgumentException("Error"); 26 | System.out.println("Test MaxHeap completed."); 27 | 28 | long endTime = System.nanoTime(); 29 | 30 | return (endTime - startTime) / 1000000000.0; 31 | } 32 | 33 | public static void main(String[] args) { 34 | 35 | int n = 1000000; 36 | 37 | Random random = new Random(); 38 | Integer[] testData1 = new Integer[n]; 39 | for(int i = 0 ; i < n ; i ++) 40 | testData1[i] = random.nextInt(Integer.MAX_VALUE); 41 | 42 | Integer[] testData2 = Arrays.copyOf(testData1, n); 43 | 44 | double time1 = testHeap(testData1, false); 45 | System.out.println("Without heapify: " + time1 + " s"); 46 | 47 | double time2 = testHeap(testData2, true); 48 | System.out.println("With heapify: " + time2 + " s"); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /14-Hash-Table/05-Hash-Table-Implementation/src/HashTable.java: -------------------------------------------------------------------------------- 1 | import java.util.TreeMap; 2 | 3 | public class HashTable { 4 | 5 | private TreeMap[] hashtable; 6 | private int size; 7 | private int M; 8 | 9 | public HashTable(int M){ 10 | this.M = M; 11 | size = 0; 12 | hashtable = new TreeMap[M]; 13 | for(int i = 0 ; i < M ; i ++) 14 | hashtable[i] = new TreeMap<>(); 15 | } 16 | 17 | public HashTable(){ 18 | this(97); 19 | } 20 | 21 | private int hash(K key){ 22 | return (key.hashCode() & 0x7fffffff) % M; 23 | } 24 | 25 | public int getSize(){ 26 | return size; 27 | } 28 | 29 | public void add(K key, V value){ 30 | TreeMap map = hashtable[hash(key)]; 31 | if(map.containsKey(key)) 32 | map.put(key, value); 33 | else{ 34 | map.put(key, value); 35 | size ++; 36 | } 37 | } 38 | 39 | public V remove(K key){ 40 | V ret = null; 41 | TreeMap map = hashtable[hash(key)]; 42 | if(map.containsKey(key)){ 43 | ret = map.remove(key); 44 | size --; 45 | } 46 | return ret; 47 | } 48 | 49 | public void set(K key, V value){ 50 | TreeMap map = hashtable[hash(key)]; 51 | if(!map.containsKey(key)) 52 | throw new IllegalArgumentException(key + " doesn't exist!"); 53 | 54 | map.put(key, value); 55 | } 56 | 57 | public boolean contains(K key){ 58 | return hashtable[hash(key)].containsKey(key); 59 | } 60 | 61 | public V get(K key){ 62 | return hashtable[hash(key)].get(key); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /06-Binary-Search-Tree/Optional-03-Binary-Tree-Classic-Nonrecursive-Traversal/Postorder/src/Solution1.java: -------------------------------------------------------------------------------- 1 | /// Source : https://leetcode.com/problems/binary-tree-postorder-traversal/description/ 2 | /// Author : liuyubobobo 3 | /// Time : 2018-05-30 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.Stack; 8 | 9 | // Non-Recursive 10 | // Using a tag to record whether the node has been visited 11 | // 12 | // Time Complexity: O(n), n is the node number in the tree 13 | // Space Complexity: O(h), h is the height of the tree 14 | public class Solution1 { 15 | 16 | private class TagNode{ 17 | TreeNode node; 18 | boolean isFirst; 19 | TagNode(TreeNode node){ 20 | this.node = node; 21 | this.isFirst = false; 22 | } 23 | }; 24 | 25 | public List postorderTraversal(TreeNode root) { 26 | 27 | ArrayList res = new ArrayList(); 28 | if(root == null) 29 | return res; 30 | 31 | Stack stack = new Stack<>(); 32 | TreeNode cur = root; 33 | while(cur != null || !stack.empty()){ 34 | 35 | while(cur != null){ 36 | stack.push(new TagNode(cur)); 37 | cur = cur.left; 38 | } 39 | 40 | TagNode tagNode = stack.pop(); 41 | cur = tagNode.node; 42 | if(tagNode.isFirst == false){ 43 | tagNode.isFirst = true; 44 | stack.push(tagNode); 45 | cur = cur.right; 46 | } 47 | else{ 48 | res.add(cur.val); 49 | cur = null; 50 | } 51 | } 52 | return res; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /06-Binary-Search-Tree/05-Search-in-BST/src/BST.java: -------------------------------------------------------------------------------- 1 | public class BST> { 2 | 3 | private class Node { 4 | public E e; 5 | public Node left, right; 6 | 7 | public Node(E e) { 8 | this.e = e; 9 | left = null; 10 | right = null; 11 | } 12 | } 13 | 14 | private Node root; 15 | private int size; 16 | 17 | public BST(){ 18 | root = null; 19 | size = 0; 20 | } 21 | 22 | public int size(){ 23 | return size; 24 | } 25 | 26 | public boolean isEmpty(){ 27 | return size == 0; 28 | } 29 | 30 | // 向二分搜索树中添加新的元素e 31 | public void add(E e){ 32 | root = add(root, e); 33 | } 34 | 35 | // 向以node为根的二分搜索树中插入元素e,递归算法 36 | // 返回插入新节点后二分搜索树的根 37 | private Node add(Node node, E e){ 38 | if(node == null){ 39 | size ++; 40 | return new Node(e); 41 | } 42 | 43 | if(e.compareTo(node.e) < 0) 44 | node.left = add(node.left, e); 45 | else if(e.compareTo(node.e) > 0) 46 | node.right = add(node.right, e); 47 | 48 | return node; 49 | } 50 | 51 | // 看二分搜索树中是否包含元素e 52 | public boolean contains(E e){ 53 | return contains(root, e); 54 | } 55 | 56 | // 看以node为根的二分搜索树中是否包含元素e, 递归算法 57 | private boolean contains(Node node, E e){ 58 | 59 | if(node == null) 60 | return false; 61 | 62 | if(e.compareTo(node.e) == 0) 63 | return true; 64 | else if(e.compareTo(node.e) < 0) 65 | return contains(node.left, e); 66 | else // e.compareTo(node.e) > 0 67 | return contains(node.right, e); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /11-Union-Find/07-More-about-Union-Find/src/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.Random; 2 | 3 | public class Main { 4 | 5 | private static double testUF(UF uf, int m){ 6 | 7 | int size = uf.getSize(); 8 | Random random = new Random(); 9 | 10 | long startTime = System.nanoTime(); 11 | 12 | 13 | for(int i = 0 ; i < m ; i ++){ 14 | int a = random.nextInt(size); 15 | int b = random.nextInt(size); 16 | uf.unionElements(a, b); 17 | } 18 | 19 | for(int i = 0 ; i < m ; i ++){ 20 | int a = random.nextInt(size); 21 | int b = random.nextInt(size); 22 | uf.isConnected(a, b); 23 | } 24 | 25 | long endTime = System.nanoTime(); 26 | 27 | double time = (endTime - startTime) / 1000000000.0; 28 | return time; 29 | } 30 | 31 | public static void main(String[] args) { 32 | 33 | int size = 10000000; 34 | int m = 10000000; 35 | 36 | // UnionFind1 uf1 = new UnionFind1(size); 37 | // System.out.println("UnionFind1 : " + testUF(uf1, m) + " s"); 38 | // 39 | // UnionFind2 uf2 = new UnionFind2(size); 40 | // System.out.println("UnionFind2 : " + testUF(uf2, m) + " s"); 41 | 42 | UnionFind3 uf3 = new UnionFind3(size); 43 | System.out.println("UnionFind3 : " + testUF(uf3, m) + " s"); 44 | 45 | UnionFind4 uf4 = new UnionFind4(size); 46 | System.out.println("UnionFind4 : " + testUF(uf4, m) + " s"); 47 | 48 | UnionFind5 uf5 = new UnionFind5(size); 49 | System.out.println("UnionFind5 : " + testUF(uf5, m) + " s"); 50 | 51 | UnionFind6 uf6 = new UnionFind6(size); 52 | System.out.println("UnionFind6 : " + testUF(uf6, m) + " s"); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /03-Stacks-and-Queues/05-Array-Queue/src/ArrayQueue.java: -------------------------------------------------------------------------------- 1 | public class ArrayQueue implements Queue { 2 | 3 | private Array array; 4 | 5 | public ArrayQueue(int capacity){ 6 | array = new Array<>(capacity); 7 | } 8 | 9 | public ArrayQueue(){ 10 | array = new Array<>(); 11 | } 12 | 13 | @Override 14 | public int getSize(){ 15 | return array.getSize(); 16 | } 17 | 18 | @Override 19 | public boolean isEmpty(){ 20 | return array.isEmpty(); 21 | } 22 | 23 | public int getCapacity(){ 24 | return array.getCapacity(); 25 | } 26 | 27 | @Override 28 | public void enqueue(E e){ 29 | array.addLast(e); 30 | } 31 | 32 | @Override 33 | public E dequeue(){ 34 | return array.removeFirst(); 35 | } 36 | 37 | @Override 38 | public E getFront(){ 39 | return array.getFirst(); 40 | } 41 | 42 | @Override 43 | public String toString(){ 44 | StringBuilder res = new StringBuilder(); 45 | res.append("Queue: "); 46 | res.append("front ["); 47 | for(int i = 0 ; i < array.getSize() ; i ++){ 48 | res.append(array.get(i)); 49 | if(i != array.getSize() - 1) 50 | res.append(", "); 51 | } 52 | res.append("] tail"); 53 | return res.toString(); 54 | } 55 | 56 | public static void main(String[] args) { 57 | 58 | ArrayQueue queue = new ArrayQueue<>(); 59 | for(int i = 0 ; i < 10 ; i ++){ 60 | queue.enqueue(i); 61 | System.out.println(queue); 62 | if(i % 3 == 2){ 63 | queue.dequeue(); 64 | System.out.println(queue); 65 | } 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /03-Stacks-and-Queues/06-Loop-Queue/src/ArrayQueue.java: -------------------------------------------------------------------------------- 1 | public class ArrayQueue implements Queue { 2 | 3 | private Array array; 4 | 5 | public ArrayQueue(int capacity){ 6 | array = new Array<>(capacity); 7 | } 8 | 9 | public ArrayQueue(){ 10 | array = new Array<>(); 11 | } 12 | 13 | @Override 14 | public int getSize(){ 15 | return array.getSize(); 16 | } 17 | 18 | @Override 19 | public boolean isEmpty(){ 20 | return array.isEmpty(); 21 | } 22 | 23 | public int getCapacity(){ 24 | return array.getCapacity(); 25 | } 26 | 27 | @Override 28 | public void enqueue(E e){ 29 | array.addLast(e); 30 | } 31 | 32 | @Override 33 | public E dequeue(){ 34 | return array.removeFirst(); 35 | } 36 | 37 | @Override 38 | public E getFront(){ 39 | return array.getFirst(); 40 | } 41 | 42 | @Override 43 | public String toString(){ 44 | 45 | StringBuilder res = new StringBuilder(); 46 | res.append("Queue: "); 47 | res.append("front ["); 48 | for(int i = 0 ; i < array.getSize() ; i ++){ 49 | res.append(array.get(i)); 50 | if(i != array.getSize() - 1) 51 | res.append(", "); 52 | } 53 | res.append("] tail"); 54 | return res.toString(); 55 | } 56 | 57 | public static void main(String[] args){ 58 | 59 | ArrayQueue queue = new ArrayQueue<>(); 60 | for(int i = 0 ; i < 10 ; i ++){ 61 | queue.enqueue(i); 62 | System.out.println(queue); 63 | 64 | if(i % 3 == 2){ 65 | queue.dequeue(); 66 | System.out.println(queue); 67 | } 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /03-Stacks-and-Queues/08-Queues-Comparison/src/ArrayQueue.java: -------------------------------------------------------------------------------- 1 | public class ArrayQueue implements Queue { 2 | 3 | private Array array; 4 | 5 | public ArrayQueue(int capacity){ 6 | array = new Array<>(capacity); 7 | } 8 | 9 | public ArrayQueue(){ 10 | array = new Array<>(); 11 | } 12 | 13 | @Override 14 | public int getSize(){ 15 | return array.getSize(); 16 | } 17 | 18 | @Override 19 | public boolean isEmpty(){ 20 | return array.isEmpty(); 21 | } 22 | 23 | public int getCapacity(){ 24 | return array.getCapacity(); 25 | } 26 | 27 | @Override 28 | public void enqueue(E e){ 29 | array.addLast(e); 30 | } 31 | 32 | @Override 33 | public E dequeue(){ 34 | return array.removeFirst(); 35 | } 36 | 37 | @Override 38 | public E getFront(){ 39 | return array.getFirst(); 40 | } 41 | 42 | @Override 43 | public String toString(){ 44 | 45 | StringBuilder res = new StringBuilder(); 46 | res.append("Queue: "); 47 | res.append("front ["); 48 | for(int i = 0 ; i < array.getSize() ; i ++){ 49 | res.append(array.get(i)); 50 | if(i != array.getSize() - 1) 51 | res.append(", "); 52 | } 53 | res.append("] tail"); 54 | return res.toString(); 55 | } 56 | 57 | public static void main(String[] args){ 58 | 59 | ArrayQueue queue = new ArrayQueue<>(); 60 | for(int i = 0 ; i < 10 ; i ++){ 61 | queue.enqueue(i); 62 | System.out.println(queue); 63 | 64 | if(i % 3 == 2){ 65 | queue.dequeue(); 66 | System.out.println(queue); 67 | } 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /04-Linked-List/07-Implement-Queue-in-LinkedList/src/ArrayQueue.java: -------------------------------------------------------------------------------- 1 | public class ArrayQueue implements Queue { 2 | 3 | private Array array; 4 | 5 | public ArrayQueue(int capacity){ 6 | array = new Array<>(capacity); 7 | } 8 | 9 | public ArrayQueue(){ 10 | array = new Array<>(); 11 | } 12 | 13 | @Override 14 | public int getSize(){ 15 | return array.getSize(); 16 | } 17 | 18 | @Override 19 | public boolean isEmpty(){ 20 | return array.isEmpty(); 21 | } 22 | 23 | public int getCapacity(){ 24 | return array.getCapacity(); 25 | } 26 | 27 | @Override 28 | public void enqueue(E e){ 29 | array.addLast(e); 30 | } 31 | 32 | @Override 33 | public E dequeue(){ 34 | return array.removeFirst(); 35 | } 36 | 37 | @Override 38 | public E getFront(){ 39 | return array.getFirst(); 40 | } 41 | 42 | @Override 43 | public String toString(){ 44 | 45 | StringBuilder res = new StringBuilder(); 46 | res.append("Queue: "); 47 | res.append("front ["); 48 | for(int i = 0 ; i < array.getSize() ; i ++){ 49 | res.append(array.get(i)); 50 | if(i != array.getSize() - 1) 51 | res.append(", "); 52 | } 53 | res.append("] tail"); 54 | return res.toString(); 55 | } 56 | 57 | public static void main(String[] args){ 58 | 59 | ArrayQueue queue = new ArrayQueue<>(); 60 | for(int i = 0 ; i < 10 ; i ++){ 61 | queue.enqueue(i); 62 | System.out.println(queue); 63 | 64 | if(i % 3 == 2){ 65 | queue.dequeue(); 66 | System.out.println(queue); 67 | } 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /03-Stacks-and-Queues/07-Implementation-of-Loop-Queue/src/ArrayQueue.java: -------------------------------------------------------------------------------- 1 | public class ArrayQueue implements Queue { 2 | 3 | private Array array; 4 | 5 | public ArrayQueue(int capacity){ 6 | array = new Array<>(capacity); 7 | } 8 | 9 | public ArrayQueue(){ 10 | array = new Array<>(); 11 | } 12 | 13 | @Override 14 | public int getSize(){ 15 | return array.getSize(); 16 | } 17 | 18 | @Override 19 | public boolean isEmpty(){ 20 | return array.isEmpty(); 21 | } 22 | 23 | public int getCapacity(){ 24 | return array.getCapacity(); 25 | } 26 | 27 | @Override 28 | public void enqueue(E e){ 29 | array.addLast(e); 30 | } 31 | 32 | @Override 33 | public E dequeue(){ 34 | return array.removeFirst(); 35 | } 36 | 37 | @Override 38 | public E getFront(){ 39 | return array.getFirst(); 40 | } 41 | 42 | @Override 43 | public String toString(){ 44 | 45 | StringBuilder res = new StringBuilder(); 46 | res.append("Queue: "); 47 | res.append("front ["); 48 | for(int i = 0 ; i < array.getSize() ; i ++){ 49 | res.append(array.get(i)); 50 | if(i != array.getSize() - 1) 51 | res.append(", "); 52 | } 53 | res.append("] tail"); 54 | return res.toString(); 55 | } 56 | 57 | public static void main(String[] args){ 58 | 59 | ArrayQueue queue = new ArrayQueue<>(); 60 | for(int i = 0 ; i < 10 ; i ++){ 61 | queue.enqueue(i); 62 | System.out.println(queue); 63 | 64 | if(i % 3 == 2){ 65 | queue.dequeue(); 66 | System.out.println(queue); 67 | } 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /12-AVL-Tree/07-Remove-Elements-in-AVL-Tree/src/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class Main { 4 | 5 | public static void main(String[] args) { 6 | 7 | System.out.println("Pride and Prejudice"); 8 | 9 | ArrayList words = new ArrayList<>(); 10 | if(FileOperation.readFile("pride-and-prejudice.txt", words)) { 11 | System.out.println("Total words: " + words.size()); 12 | 13 | // Collections.sort(words); 14 | 15 | // Test BST 16 | long startTime = System.nanoTime(); 17 | 18 | BST bst = new BST<>(); 19 | for (String word : words) { 20 | if (bst.contains(word)) 21 | bst.set(word, bst.get(word) + 1); 22 | else 23 | bst.add(word, 1); 24 | } 25 | 26 | for(String word: words) 27 | bst.contains(word); 28 | 29 | long endTime = System.nanoTime(); 30 | 31 | double time = (endTime - startTime) / 1000000000.0; 32 | System.out.println("BST: " + time + " s"); 33 | 34 | 35 | // Test AVL 36 | startTime = System.nanoTime(); 37 | 38 | AVLTree avl = new AVLTree<>(); 39 | for (String word : words) { 40 | if (avl.contains(word)) 41 | avl.set(word, avl.get(word) + 1); 42 | else 43 | avl.add(word, 1); 44 | } 45 | 46 | for(String word: words) 47 | avl.contains(word); 48 | 49 | endTime = System.nanoTime(); 50 | 51 | time = (endTime - startTime) / 1000000000.0; 52 | System.out.println("AVL: " + time + " s"); 53 | } 54 | 55 | System.out.println(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /07-Set-and-Map/02-LinkedListSet/src/BSTSet.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class BSTSet> implements Set { 4 | 5 | private BST bst; 6 | 7 | public BSTSet(){ 8 | bst = new BST<>(); 9 | } 10 | 11 | @Override 12 | public int getSize(){ 13 | return bst.size(); 14 | } 15 | 16 | @Override 17 | public boolean isEmpty(){ 18 | return bst.isEmpty(); 19 | } 20 | 21 | @Override 22 | public void add(E e){ 23 | bst.add(e); 24 | } 25 | 26 | @Override 27 | public boolean contains(E e){ 28 | return bst.contains(e); 29 | } 30 | 31 | @Override 32 | public void remove(E e){ 33 | bst.remove(e); 34 | } 35 | 36 | public static void main(String[] args) { 37 | 38 | System.out.println("Pride and Prejudice"); 39 | 40 | ArrayList words1 = new ArrayList<>(); 41 | if(FileOperation.readFile("pride-and-prejudice.txt", words1)) { 42 | System.out.println("Total words: " + words1.size()); 43 | 44 | BSTSet set1 = new BSTSet<>(); 45 | for (String word : words1) 46 | set1.add(word); 47 | System.out.println("Total different words: " + set1.getSize()); 48 | } 49 | 50 | System.out.println(); 51 | 52 | System.out.println("A Tale of Two Cities"); 53 | 54 | ArrayList words2 = new ArrayList<>(); 55 | if(FileOperation.readFile("a-tale-of-two-cities.txt", words2)){ 56 | System.out.println("Total words: " + words2.size()); 57 | 58 | BSTSet set2 = new BSTSet<>(); 59 | for(String word: words2) 60 | set2.add(word); 61 | System.out.println("Total different words: " + set2.getSize()); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /11-Union-Find/06-Path-Compression/src/UnionFind3.java: -------------------------------------------------------------------------------- 1 | // 我们的第三版Union-Find 2 | public class UnionFind3 implements UF{ 3 | 4 | private int[] parent; // parent[i]表示第一个元素所指向的父节点 5 | private int[] sz; // sz[i]表示以i为根的集合中元素个数 6 | 7 | // 构造函数 8 | public UnionFind3(int size){ 9 | 10 | parent = new int[size]; 11 | sz = new int[size]; 12 | 13 | // 初始化, 每一个parent[i]指向自己, 表示每一个元素自己自成一个集合 14 | for(int i = 0 ; i < size ; i ++){ 15 | parent[i] = i; 16 | sz[i] = 1; 17 | } 18 | } 19 | 20 | @Override 21 | public int getSize(){ 22 | return parent.length; 23 | } 24 | 25 | // 查找过程, 查找元素p所对应的集合编号 26 | // O(h)复杂度, h为树的高度 27 | private int find(int p){ 28 | if(p < 0 || p >= parent.length) 29 | throw new IllegalArgumentException("p is out of bound."); 30 | 31 | // 不断去查询自己的父亲节点, 直到到达根节点 32 | // 根节点的特点: parent[p] == p 33 | while( p != parent[p] ) 34 | p = parent[p]; 35 | return p; 36 | } 37 | 38 | // 查看元素p和元素q是否所属一个集合 39 | // O(h)复杂度, h为树的高度 40 | @Override 41 | public boolean isConnected( int p , int q ){ 42 | return find(p) == find(q); 43 | } 44 | 45 | // 合并元素p和元素q所属的集合 46 | // O(h)复杂度, h为树的高度 47 | @Override 48 | public void unionElements(int p, int q){ 49 | 50 | int pRoot = find(p); 51 | int qRoot = find(q); 52 | 53 | if(pRoot == qRoot) 54 | return; 55 | 56 | // 根据两个元素所在树的元素个数不同判断合并方向 57 | // 将元素个数少的集合合并到元素个数多的集合上 58 | if(sz[pRoot] < sz[qRoot]){ 59 | parent[pRoot] = qRoot; 60 | sz[qRoot] += sz[pRoot]; 61 | } 62 | else{ // sz[qRoot] <= sz[pRoot] 63 | parent[qRoot] = pRoot; 64 | sz[pRoot] += sz[qRoot]; 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /11-Union-Find/04-Optimized-by-Size/src/UnionFind3.java: -------------------------------------------------------------------------------- 1 | // 我们的第三版Union-Find 2 | public class UnionFind3 implements UF{ 3 | 4 | private int[] parent; // parent[i]表示第一个元素所指向的父节点 5 | private int[] sz; // sz[i]表示以i为根的集合中元素个数 6 | 7 | // 构造函数 8 | public UnionFind3(int size){ 9 | 10 | parent = new int[size]; 11 | sz = new int[size]; 12 | 13 | // 初始化, 每一个parent[i]指向自己, 表示每一个元素自己自成一个集合 14 | for(int i = 0 ; i < size ; i ++){ 15 | parent[i] = i; 16 | sz[i] = 1; 17 | } 18 | } 19 | 20 | @Override 21 | public int getSize(){ 22 | return parent.length; 23 | } 24 | 25 | // 查找过程, 查找元素p所对应的集合编号 26 | // O(h)复杂度, h为树的高度 27 | private int find(int p){ 28 | if(p < 0 || p >= parent.length) 29 | throw new IllegalArgumentException("p is out of bound."); 30 | 31 | // 不断去查询自己的父亲节点, 直到到达根节点 32 | // 根节点的特点: parent[p] == p 33 | while( p != parent[p] ) 34 | p = parent[p]; 35 | return p; 36 | } 37 | 38 | // 查看元素p和元素q是否所属一个集合 39 | // O(h)复杂度, h为树的高度 40 | @Override 41 | public boolean isConnected( int p , int q ){ 42 | return find(p) == find(q); 43 | } 44 | 45 | // 合并元素p和元素q所属的集合 46 | // O(h)复杂度, h为树的高度 47 | @Override 48 | public void unionElements(int p, int q){ 49 | 50 | int pRoot = find(p); 51 | int qRoot = find(q); 52 | 53 | if(pRoot == qRoot) 54 | return; 55 | 56 | // 根据两个元素所在树的元素个数不同判断合并方向 57 | // 将元素个数少的集合合并到元素个数多的集合上 58 | if(sz[pRoot] < sz[qRoot]){ 59 | parent[pRoot] = qRoot; 60 | sz[qRoot] += sz[pRoot]; 61 | } 62 | else{ // sz[qRoot] <= sz[pRoot] 63 | parent[qRoot] = pRoot; 64 | sz[pRoot] += sz[qRoot]; 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /11-Union-Find/05-Optimized-by-Rank/src/UnionFind3.java: -------------------------------------------------------------------------------- 1 | // 我们的第三版Union-Find 2 | public class UnionFind3 implements UF{ 3 | 4 | private int[] parent; // parent[i]表示第一个元素所指向的父节点 5 | private int[] sz; // sz[i]表示以i为根的集合中元素个数 6 | 7 | // 构造函数 8 | public UnionFind3(int size){ 9 | 10 | parent = new int[size]; 11 | sz = new int[size]; 12 | 13 | // 初始化, 每一个parent[i]指向自己, 表示每一个元素自己自成一个集合 14 | for(int i = 0 ; i < size ; i ++){ 15 | parent[i] = i; 16 | sz[i] = 1; 17 | } 18 | } 19 | 20 | @Override 21 | public int getSize(){ 22 | return parent.length; 23 | } 24 | 25 | // 查找过程, 查找元素p所对应的集合编号 26 | // O(h)复杂度, h为树的高度 27 | private int find(int p){ 28 | if(p < 0 || p >= parent.length) 29 | throw new IllegalArgumentException("p is out of bound."); 30 | 31 | // 不断去查询自己的父亲节点, 直到到达根节点 32 | // 根节点的特点: parent[p] == p 33 | while( p != parent[p] ) 34 | p = parent[p]; 35 | return p; 36 | } 37 | 38 | // 查看元素p和元素q是否所属一个集合 39 | // O(h)复杂度, h为树的高度 40 | @Override 41 | public boolean isConnected( int p , int q ){ 42 | return find(p) == find(q); 43 | } 44 | 45 | // 合并元素p和元素q所属的集合 46 | // O(h)复杂度, h为树的高度 47 | @Override 48 | public void unionElements(int p, int q){ 49 | 50 | int pRoot = find(p); 51 | int qRoot = find(q); 52 | 53 | if(pRoot == qRoot) 54 | return; 55 | 56 | // 根据两个元素所在树的元素个数不同判断合并方向 57 | // 将元素个数少的集合合并到元素个数多的集合上 58 | if(sz[pRoot] < sz[qRoot]){ 59 | parent[pRoot] = qRoot; 60 | sz[qRoot] += sz[pRoot]; 61 | } 62 | else{ // sz[qRoot] <= sz[pRoot] 63 | parent[qRoot] = pRoot; 64 | sz[pRoot] += sz[qRoot]; 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /11-Union-Find/07-More-about-Union-Find/src/UnionFind3.java: -------------------------------------------------------------------------------- 1 | // 我们的第三版Union-Find 2 | public class UnionFind3 implements UF{ 3 | 4 | private int[] parent; // parent[i]表示第一个元素所指向的父节点 5 | private int[] sz; // sz[i]表示以i为根的集合中元素个数 6 | 7 | // 构造函数 8 | public UnionFind3(int size){ 9 | 10 | parent = new int[size]; 11 | sz = new int[size]; 12 | 13 | // 初始化, 每一个parent[i]指向自己, 表示每一个元素自己自成一个集合 14 | for(int i = 0 ; i < size ; i ++){ 15 | parent[i] = i; 16 | sz[i] = 1; 17 | } 18 | } 19 | 20 | @Override 21 | public int getSize(){ 22 | return parent.length; 23 | } 24 | 25 | // 查找过程, 查找元素p所对应的集合编号 26 | // O(h)复杂度, h为树的高度 27 | private int find(int p){ 28 | if(p < 0 || p >= parent.length) 29 | throw new IllegalArgumentException("p is out of bound."); 30 | 31 | // 不断去查询自己的父亲节点, 直到到达根节点 32 | // 根节点的特点: parent[p] == p 33 | while( p != parent[p] ) 34 | p = parent[p]; 35 | return p; 36 | } 37 | 38 | // 查看元素p和元素q是否所属一个集合 39 | // O(h)复杂度, h为树的高度 40 | @Override 41 | public boolean isConnected( int p , int q ){ 42 | return find(p) == find(q); 43 | } 44 | 45 | // 合并元素p和元素q所属的集合 46 | // O(h)复杂度, h为树的高度 47 | @Override 48 | public void unionElements(int p, int q){ 49 | 50 | int pRoot = find(p); 51 | int qRoot = find(q); 52 | 53 | if(pRoot == qRoot) 54 | return; 55 | 56 | // 根据两个元素所在树的元素个数不同判断合并方向 57 | // 将元素个数少的集合合并到元素个数多的集合上 58 | if(sz[pRoot] < sz[qRoot]){ 59 | parent[pRoot] = qRoot; 60 | sz[qRoot] += sz[pRoot]; 61 | } 62 | else{ // sz[qRoot] <= sz[pRoot] 63 | parent[qRoot] = pRoot; 64 | sz[pRoot] += sz[qRoot]; 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /12-AVL-Tree/08-Map-and-Set-in-AVL-Tree/src/BSTSet.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class BSTSet> implements Set { 4 | 5 | private BST bst; 6 | 7 | public BSTSet(){ 8 | bst = new BST<>(); 9 | } 10 | 11 | @Override 12 | public int getSize(){ 13 | return bst.size(); 14 | } 15 | 16 | @Override 17 | public boolean isEmpty(){ 18 | return bst.isEmpty(); 19 | } 20 | 21 | @Override 22 | public void add(E e){ 23 | bst.add(e); 24 | } 25 | 26 | @Override 27 | public boolean contains(E e){ 28 | return bst.contains(e); 29 | } 30 | 31 | @Override 32 | public void remove(E e){ 33 | bst.remove(e); 34 | } 35 | 36 | public static void main(String[] args) { 37 | 38 | System.out.println("Pride and Prejudice"); 39 | 40 | ArrayList words1 = new ArrayList<>(); 41 | if(FileOperation.readFile("pride-and-prejudice.txt", words1)){ 42 | System.out.println("Total words: " + words1.size()); 43 | 44 | BSTSet set1 = new BSTSet<>(); 45 | for(String word: words1) 46 | set1.add(word); 47 | System.out.println("Total different words: " + set1.getSize()); 48 | } 49 | 50 | System.out.println(); 51 | 52 | System.out.println("A Tale of Two Cities"); 53 | 54 | ArrayList words2 = new ArrayList<>(); 55 | if(FileOperation.readFile("a-tale-of-two-cities.txt", words2)){ 56 | System.out.println("Total words: " + words2.size()); 57 | 58 | BSTSet set2 = new BSTSet<>(); 59 | for(String word: words2) 60 | set2.add(word); 61 | System.out.println("Total different words: " + set2.getSize()); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /13-Red-Black-Tree/05-Keep-Root-Black-and-Left-Rotation/src/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class Main { 4 | 5 | public static void main(String[] args) { 6 | 7 | System.out.println("Pride and Prejudice"); 8 | 9 | ArrayList words = new ArrayList<>(); 10 | if(FileOperation.readFile("pride-and-prejudice.txt", words)) { 11 | System.out.println("Total words: " + words.size()); 12 | 13 | // Collections.sort(words); 14 | 15 | // Test BST 16 | long startTime = System.nanoTime(); 17 | 18 | BST bst = new BST<>(); 19 | for (String word : words) { 20 | if (bst.contains(word)) 21 | bst.set(word, bst.get(word) + 1); 22 | else 23 | bst.add(word, 1); 24 | } 25 | 26 | for(String word: words) 27 | bst.contains(word); 28 | 29 | long endTime = System.nanoTime(); 30 | 31 | double time = (endTime - startTime) / 1000000000.0; 32 | System.out.println("BST: " + time + " s"); 33 | 34 | 35 | // Test AVL 36 | startTime = System.nanoTime(); 37 | 38 | AVLTree avl = new AVLTree<>(); 39 | for (String word : words) { 40 | if (avl.contains(word)) 41 | avl.set(word, avl.get(word) + 1); 42 | else 43 | avl.add(word, 1); 44 | } 45 | 46 | for(String word: words) 47 | avl.contains(word); 48 | 49 | endTime = System.nanoTime(); 50 | 51 | time = (endTime - startTime) / 1000000000.0; 52 | System.out.println("AVL: " + time + " s"); 53 | } 54 | 55 | System.out.println(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /13-Red-Black-Tree/06-Flip-Colors-and-Right-Rotation/src/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class Main { 4 | 5 | public static void main(String[] args) { 6 | 7 | System.out.println("Pride and Prejudice"); 8 | 9 | ArrayList words = new ArrayList<>(); 10 | if(FileOperation.readFile("pride-and-prejudice.txt", words)) { 11 | System.out.println("Total words: " + words.size()); 12 | 13 | // Collections.sort(words); 14 | 15 | // Test BST 16 | long startTime = System.nanoTime(); 17 | 18 | BST bst = new BST<>(); 19 | for (String word : words) { 20 | if (bst.contains(word)) 21 | bst.set(word, bst.get(word) + 1); 22 | else 23 | bst.add(word, 1); 24 | } 25 | 26 | for(String word: words) 27 | bst.contains(word); 28 | 29 | long endTime = System.nanoTime(); 30 | 31 | double time = (endTime - startTime) / 1000000000.0; 32 | System.out.println("BST: " + time + " s"); 33 | 34 | 35 | // Test AVL 36 | startTime = System.nanoTime(); 37 | 38 | AVLTree avl = new AVLTree<>(); 39 | for (String word : words) { 40 | if (avl.contains(word)) 41 | avl.set(word, avl.get(word) + 1); 42 | else 43 | avl.add(word, 1); 44 | } 45 | 46 | for(String word: words) 47 | avl.contains(word); 48 | 49 | endTime = System.nanoTime(); 50 | 51 | time = (endTime - startTime) / 1000000000.0; 52 | System.out.println("AVL: " + time + " s"); 53 | } 54 | 55 | System.out.println(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /13-Red-Black-Tree/07-Adding-Elements-in-Red-Black-Tree/src/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class Main { 4 | 5 | public static void main(String[] args) { 6 | 7 | System.out.println("Pride and Prejudice"); 8 | 9 | ArrayList words = new ArrayList<>(); 10 | if(FileOperation.readFile("pride-and-prejudice.txt", words)) { 11 | System.out.println("Total words: " + words.size()); 12 | 13 | // Collections.sort(words); 14 | 15 | // Test BST 16 | long startTime = System.nanoTime(); 17 | 18 | BST bst = new BST<>(); 19 | for (String word : words) { 20 | if (bst.contains(word)) 21 | bst.set(word, bst.get(word) + 1); 22 | else 23 | bst.add(word, 1); 24 | } 25 | 26 | for(String word: words) 27 | bst.contains(word); 28 | 29 | long endTime = System.nanoTime(); 30 | 31 | double time = (endTime - startTime) / 1000000000.0; 32 | System.out.println("BST: " + time + " s"); 33 | 34 | 35 | // Test AVL 36 | startTime = System.nanoTime(); 37 | 38 | AVLTree avl = new AVLTree<>(); 39 | for (String word : words) { 40 | if (avl.contains(word)) 41 | avl.set(word, avl.get(word) + 1); 42 | else 43 | avl.add(word, 1); 44 | } 45 | 46 | for(String word: words) 47 | avl.contains(word); 48 | 49 | endTime = System.nanoTime(); 50 | 51 | time = (endTime - startTime) / 1000000000.0; 52 | System.out.println("AVL: " + time + " s"); 53 | } 54 | 55 | System.out.println(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /13-Red-Black-Tree/03-The-Equivalence-of-RBTree-and-2-3-Tree/src/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class Main { 4 | 5 | public static void main(String[] args) { 6 | 7 | System.out.println("Pride and Prejudice"); 8 | 9 | ArrayList words = new ArrayList<>(); 10 | if(FileOperation.readFile("pride-and-prejudice.txt", words)) { 11 | System.out.println("Total words: " + words.size()); 12 | 13 | // Collections.sort(words); 14 | 15 | // Test BST 16 | long startTime = System.nanoTime(); 17 | 18 | BST bst = new BST<>(); 19 | for (String word : words) { 20 | if (bst.contains(word)) 21 | bst.set(word, bst.get(word) + 1); 22 | else 23 | bst.add(word, 1); 24 | } 25 | 26 | for(String word: words) 27 | bst.contains(word); 28 | 29 | long endTime = System.nanoTime(); 30 | 31 | double time = (endTime - startTime) / 1000000000.0; 32 | System.out.println("BST: " + time + " s"); 33 | 34 | 35 | // Test AVL 36 | startTime = System.nanoTime(); 37 | 38 | AVLTree avl = new AVLTree<>(); 39 | for (String word : words) { 40 | if (avl.contains(word)) 41 | avl.set(word, avl.get(word) + 1); 42 | else 43 | avl.add(word, 1); 44 | } 45 | 46 | for(String word: words) 47 | avl.contains(word); 48 | 49 | endTime = System.nanoTime(); 50 | 51 | time = (endTime - startTime) / 1000000000.0; 52 | System.out.println("AVL: " + time + " s"); 53 | } 54 | 55 | System.out.println(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /07-Set-and-Map/03-Time-Complexity-of-Set/src/BSTSet.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class BSTSet> implements Set { 4 | 5 | private BST bst; 6 | 7 | public BSTSet(){ 8 | bst = new BST<>(); 9 | } 10 | 11 | @Override 12 | public int getSize(){ 13 | return bst.size(); 14 | } 15 | 16 | @Override 17 | public boolean isEmpty(){ 18 | return bst.isEmpty(); 19 | } 20 | 21 | @Override 22 | public void add(E e){ 23 | bst.add(e); 24 | } 25 | 26 | @Override 27 | public boolean contains(E e){ 28 | return bst.contains(e); 29 | } 30 | 31 | @Override 32 | public void remove(E e){ 33 | bst.remove(e); 34 | } 35 | 36 | public static void main(String[] args) { 37 | 38 | System.out.println("Pride and Prejudice"); 39 | 40 | ArrayList words1 = new ArrayList<>(); 41 | if(FileOperation.readFile("pride-and-prejudice.txt", words1)) { 42 | System.out.println("Total words: " + words1.size()); 43 | 44 | BSTSet set1 = new BSTSet<>(); 45 | for (String word : words1) 46 | set1.add(word); 47 | System.out.println("Total different words: " + set1.getSize()); 48 | } 49 | 50 | System.out.println(); 51 | 52 | 53 | System.out.println("A Tale of Two Cities"); 54 | 55 | ArrayList words2 = new ArrayList<>(); 56 | if(FileOperation.readFile("a-tale-of-two-cities.txt", words2)){ 57 | System.out.println("Total words: " + words2.size()); 58 | 59 | BSTSet set2 = new BSTSet<>(); 60 | for(String word: words2) 61 | set2.add(word); 62 | System.out.println("Total different words: " + set2.getSize()); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /10-Trie/04-Prefix-in-Trie/src/Trie208.java: -------------------------------------------------------------------------------- 1 | /// 208. Implement Trie (Prefix Tree) 2 | /// https://leetcode.com/problems/implement-trie-prefix-tree/description/ 3 | 4 | import java.util.TreeMap; 5 | 6 | public class Trie208 { 7 | 8 | private class Node{ 9 | 10 | public boolean isWord; 11 | public TreeMap next; 12 | 13 | public Node(boolean isWord){ 14 | this.isWord = isWord; 15 | next = new TreeMap<>(); 16 | } 17 | 18 | public Node(){ 19 | this(false); 20 | } 21 | } 22 | 23 | private Node root; 24 | 25 | public Trie208(){ 26 | root = new Node(); 27 | } 28 | 29 | // 向Trie中添加一个新的单词word 30 | public void insert(String word){ 31 | 32 | Node cur = root; 33 | for(int i = 0 ; i < word.length() ; i ++){ 34 | char c = word.charAt(i); 35 | if(cur.next.get(c) == null) 36 | cur.next.put(c, new Node()); 37 | cur = cur.next.get(c); 38 | } 39 | cur.isWord = true; 40 | } 41 | 42 | // 查询单词word是否在Trie中 43 | public boolean search(String word){ 44 | 45 | Node cur = root; 46 | for(int i = 0 ; i < word.length() ; i ++){ 47 | char c = word.charAt(i); 48 | if(cur.next.get(c) == null) 49 | return false; 50 | cur = cur.next.get(c); 51 | } 52 | return cur.isWord; 53 | } 54 | 55 | // 查询是否在Trie中有单词以prefix为前缀 56 | public boolean startsWith(String isPrefix){ 57 | 58 | Node cur = root; 59 | for(int i = 0 ; i < isPrefix.length() ; i ++){ 60 | char c = isPrefix.charAt(i); 61 | if(cur.next.get(c) == null) 62 | return false; 63 | cur = cur.next.get(c); 64 | } 65 | 66 | return true; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /12-AVL-Tree/06-LR-and-RL/src/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.Collections; 3 | 4 | public class Main { 5 | 6 | public static void main(String[] args) { 7 | 8 | System.out.println("Pride and Prejudice"); 9 | 10 | ArrayList words = new ArrayList<>(); 11 | if(FileOperation.readFile("pride-and-prejudice.txt", words)) { 12 | System.out.println("Total words: " + words.size()); 13 | 14 | // Collections.sort(words); 15 | 16 | // Test BST 17 | long startTime = System.nanoTime(); 18 | 19 | BST bst = new BST<>(); 20 | for (String word : words) { 21 | if (bst.contains(word)) 22 | bst.set(word, bst.get(word) + 1); 23 | else 24 | bst.add(word, 1); 25 | } 26 | 27 | for(String word: words) 28 | bst.contains(word); 29 | 30 | long endTime = System.nanoTime(); 31 | 32 | double time = (endTime - startTime) / 1000000000.0; 33 | System.out.println("BST: " + time + " s"); 34 | 35 | 36 | // Test AVL Tree 37 | startTime = System.nanoTime(); 38 | 39 | AVLTree avl = new AVLTree<>(); 40 | for (String word : words) { 41 | if (avl.contains(word)) 42 | avl.set(word, avl.get(word) + 1); 43 | else 44 | avl.add(word, 1); 45 | } 46 | 47 | for(String word: words) 48 | avl.contains(word); 49 | 50 | endTime = System.nanoTime(); 51 | 52 | time = (endTime - startTime) / 1000000000.0; 53 | System.out.println("AVL: " + time + " s"); 54 | } 55 | 56 | System.out.println(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /12-AVL-Tree/08-Map-and-Set-in-AVL-Tree/src/TestMapMain.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class TestMapMain { 4 | 5 | private static double testMap(Map map, String filename){ 6 | 7 | long startTime = System.nanoTime(); 8 | 9 | System.out.println(filename); 10 | ArrayList words = new ArrayList<>(); 11 | if(FileOperation.readFile(filename, words)) { 12 | System.out.println("Total words: " + words.size()); 13 | 14 | for (String word : words){ 15 | if(map.contains(word)) 16 | map.set(word, map.get(word) + 1); 17 | else 18 | map.add(word, 1); 19 | } 20 | 21 | System.out.println("Total different words: " + map.getSize()); 22 | System.out.println("Frequency of PRIDE: " + map.get("pride")); 23 | System.out.println("Frequency of PREJUDICE: " + map.get("prejudice")); 24 | } 25 | 26 | long endTime = System.nanoTime(); 27 | 28 | return (endTime - startTime) / 1000000000.0; 29 | } 30 | 31 | public static void main(String[] args) { 32 | 33 | String filename = "pride-and-prejudice.txt"; 34 | 35 | BSTMap bstMap = new BSTMap<>(); 36 | double time1 = testMap(bstMap, filename); 37 | System.out.println("BST Map: " + time1 + " s"); 38 | 39 | System.out.println(); 40 | 41 | LinkedListMap linkedListMap = new LinkedListMap<>(); 42 | double time2 = testMap(linkedListMap, filename); 43 | System.out.println("Linked List Map: " + time2 + " s"); 44 | 45 | System.out.println(); 46 | 47 | AVLMap avlMap = new AVLMap<>(); 48 | double time3 = testMap(avlMap, filename); 49 | System.out.println("AVL Map: " + time3 + " s"); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /08-Heap-and-Priority-Queue/08-Priority-Queue-in-Java/src/Solution3.java: -------------------------------------------------------------------------------- 1 | /// 347. Top K Frequent Elements 2 | /// https://leetcode.com/problems/top-k-frequent-elements/description/ 3 | 4 | import java.util.*; 5 | 6 | public class Solution3 { 7 | 8 | private class Freq{ 9 | 10 | public int e, freq; 11 | 12 | public Freq(int e, int freq){ 13 | this.e = e; 14 | this.freq = freq; 15 | } 16 | } 17 | 18 | public List topKFrequent(int[] nums, int k) { 19 | 20 | TreeMap map = new TreeMap<>(); 21 | for(int num: nums){ 22 | if(map.containsKey(num)) 23 | map.put(num, map.get(num) + 1); 24 | else 25 | map.put(num, 1); 26 | } 27 | 28 | PriorityQueue pq = new PriorityQueue<>(new Comparator() { 29 | @Override 30 | public int compare(Freq a, Freq b) { 31 | return a.freq - b.freq; 32 | } 33 | }); 34 | for(int key: map.keySet()){ 35 | if(pq.size() < k) 36 | pq.add(new Freq(key, map.get(key))); 37 | else if(map.get(key) > pq.peek().freq){ 38 | pq.remove(); 39 | pq.add(new Freq(key, map.get(key))); 40 | } 41 | } 42 | 43 | LinkedList res = new LinkedList<>(); 44 | while(!pq.isEmpty()) 45 | res.add(pq.remove().e); 46 | return res; 47 | } 48 | 49 | private static void printList(List nums){ 50 | for(Integer num: nums) 51 | System.out.print(num + " "); 52 | System.out.println(); 53 | } 54 | 55 | public static void main(String[] args) { 56 | 57 | int[] nums = {1, 1, 1, 2, 2, 3}; 58 | int k = 2; 59 | printList((new Solution()).topKFrequent(nums, k)); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /11-Union-Find/05-Optimized-by-Rank/src/UnionFind4.java: -------------------------------------------------------------------------------- 1 | // 我们的第四版Union-Find 2 | public class UnionFind4 implements UF { 3 | 4 | private int[] rank; // rank[i]表示以i为根的集合所表示的树的层数 5 | private int[] parent; // parent[i]表示第i个元素所指向的父节点 6 | 7 | // 构造函数 8 | public UnionFind4(int size){ 9 | 10 | rank = new int[size]; 11 | parent = new int[size]; 12 | 13 | // 初始化, 每一个parent[i]指向自己, 表示每一个元素自己自成一个集合 14 | for( int i = 0 ; i < size ; i ++ ){ 15 | parent[i] = i; 16 | rank[i] = 1; 17 | } 18 | } 19 | 20 | @Override 21 | public int getSize(){ 22 | return parent.length; 23 | } 24 | 25 | // 查找过程, 查找元素p所对应的集合编号 26 | // O(h)复杂度, h为树的高度 27 | private int find(int p){ 28 | if(p < 0 || p >= parent.length) 29 | throw new IllegalArgumentException("p is out of bound."); 30 | 31 | // 不断去查询自己的父亲节点, 直到到达根节点 32 | // 根节点的特点: parent[p] == p 33 | while(p != parent[p]) 34 | p = parent[p]; 35 | return p; 36 | } 37 | 38 | // 查看元素p和元素q是否所属一个集合 39 | // O(h)复杂度, h为树的高度 40 | @Override 41 | public boolean isConnected( int p , int q ){ 42 | return find(p) == find(q); 43 | } 44 | 45 | // 合并元素p和元素q所属的集合 46 | // O(h)复杂度, h为树的高度 47 | @Override 48 | public void unionElements(int p, int q){ 49 | 50 | int pRoot = find(p); 51 | int qRoot = find(q); 52 | 53 | if( pRoot == qRoot ) 54 | return; 55 | 56 | // 根据两个元素所在树的rank不同判断合并方向 57 | // 将rank低的集合合并到rank高的集合上 58 | if(rank[pRoot] < rank[qRoot]) 59 | parent[pRoot] = qRoot; 60 | else if(rank[qRoot] < rank[pRoot]) 61 | parent[qRoot] = pRoot; 62 | else{ // rank[pRoot] == rank[qRoot] 63 | parent[pRoot] = qRoot; 64 | rank[qRoot] += 1; // 此时, 我维护rank的值 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /11-Union-Find/06-Path-Compression/src/UnionFind4.java: -------------------------------------------------------------------------------- 1 | // 我们的第四版Union-Find 2 | public class UnionFind4 implements UF { 3 | 4 | private int[] rank; // rank[i]表示以i为根的集合所表示的树的层数 5 | private int[] parent; // parent[i]表示第i个元素所指向的父节点 6 | 7 | // 构造函数 8 | public UnionFind4(int size){ 9 | 10 | rank = new int[size]; 11 | parent = new int[size]; 12 | 13 | // 初始化, 每一个parent[i]指向自己, 表示每一个元素自己自成一个集合 14 | for( int i = 0 ; i < size ; i ++ ){ 15 | parent[i] = i; 16 | rank[i] = 1; 17 | } 18 | } 19 | 20 | @Override 21 | public int getSize(){ 22 | return parent.length; 23 | } 24 | 25 | // 查找过程, 查找元素p所对应的集合编号 26 | // O(h)复杂度, h为树的高度 27 | private int find(int p){ 28 | if(p < 0 || p >= parent.length) 29 | throw new IllegalArgumentException("p is out of bound."); 30 | 31 | // 不断去查询自己的父亲节点, 直到到达根节点 32 | // 根节点的特点: parent[p] == p 33 | while(p != parent[p]) 34 | p = parent[p]; 35 | return p; 36 | } 37 | 38 | // 查看元素p和元素q是否所属一个集合 39 | // O(h)复杂度, h为树的高度 40 | @Override 41 | public boolean isConnected( int p , int q ){ 42 | return find(p) == find(q); 43 | } 44 | 45 | // 合并元素p和元素q所属的集合 46 | // O(h)复杂度, h为树的高度 47 | @Override 48 | public void unionElements(int p, int q){ 49 | 50 | int pRoot = find(p); 51 | int qRoot = find(q); 52 | 53 | if( pRoot == qRoot ) 54 | return; 55 | 56 | // 根据两个元素所在树的rank不同判断合并方向 57 | // 将rank低的集合合并到rank高的集合上 58 | if(rank[pRoot] < rank[qRoot]) 59 | parent[pRoot] = qRoot; 60 | else if(rank[qRoot] < rank[pRoot]) 61 | parent[qRoot] = pRoot; 62 | else{ // rank[pRoot] == rank[qRoot] 63 | parent[pRoot] = qRoot; 64 | rank[qRoot] += 1; // 此时, 我维护rank的值 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /11-Union-Find/07-More-about-Union-Find/src/UnionFind4.java: -------------------------------------------------------------------------------- 1 | // 我们的第四版Union-Find 2 | public class UnionFind4 implements UF { 3 | 4 | private int[] rank; // rank[i]表示以i为根的集合所表示的树的层数 5 | private int[] parent; // parent[i]表示第i个元素所指向的父节点 6 | 7 | // 构造函数 8 | public UnionFind4(int size){ 9 | 10 | rank = new int[size]; 11 | parent = new int[size]; 12 | 13 | // 初始化, 每一个parent[i]指向自己, 表示每一个元素自己自成一个集合 14 | for( int i = 0 ; i < size ; i ++ ){ 15 | parent[i] = i; 16 | rank[i] = 1; 17 | } 18 | } 19 | 20 | @Override 21 | public int getSize(){ 22 | return parent.length; 23 | } 24 | 25 | // 查找过程, 查找元素p所对应的集合编号 26 | // O(h)复杂度, h为树的高度 27 | private int find(int p){ 28 | if(p < 0 || p >= parent.length) 29 | throw new IllegalArgumentException("p is out of bound."); 30 | 31 | // 不断去查询自己的父亲节点, 直到到达根节点 32 | // 根节点的特点: parent[p] == p 33 | while(p != parent[p]) 34 | p = parent[p]; 35 | return p; 36 | } 37 | 38 | // 查看元素p和元素q是否所属一个集合 39 | // O(h)复杂度, h为树的高度 40 | @Override 41 | public boolean isConnected( int p , int q ){ 42 | return find(p) == find(q); 43 | } 44 | 45 | // 合并元素p和元素q所属的集合 46 | // O(h)复杂度, h为树的高度 47 | @Override 48 | public void unionElements(int p, int q){ 49 | 50 | int pRoot = find(p); 51 | int qRoot = find(q); 52 | 53 | if( pRoot == qRoot ) 54 | return; 55 | 56 | // 根据两个元素所在树的rank不同判断合并方向 57 | // 将rank低的集合合并到rank高的集合上 58 | if(rank[pRoot] < rank[qRoot]) 59 | parent[pRoot] = qRoot; 60 | else if(rank[qRoot] < rank[pRoot]) 61 | parent[qRoot] = pRoot; 62 | else{ // rank[pRoot] == rank[qRoot] 63 | parent[pRoot] = qRoot; 64 | rank[qRoot] += 1; // 此时, 我维护rank的值 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /08-Heap-and-Priority-Queue/08-Priority-Queue-in-Java/src/Solution2.java: -------------------------------------------------------------------------------- 1 | /// 347. Top K Frequent Elements 2 | /// https://leetcode.com/problems/top-k-frequent-elements/description/ 3 | 4 | import java.util.*; 5 | 6 | public class Solution2 { 7 | 8 | private class Freq{ 9 | 10 | public int e, freq; 11 | 12 | public Freq(int e, int freq){ 13 | this.e = e; 14 | this.freq = freq; 15 | } 16 | } 17 | 18 | private class FreqComparator implements Comparator{ 19 | 20 | @Override 21 | public int compare(Freq a, Freq b){ 22 | return a.freq - b.freq; 23 | } 24 | } 25 | 26 | public List topKFrequent(int[] nums, int k) { 27 | 28 | TreeMap map = new TreeMap<>(); 29 | for(int num: nums){ 30 | if(map.containsKey(num)) 31 | map.put(num, map.get(num) + 1); 32 | else 33 | map.put(num, 1); 34 | } 35 | 36 | PriorityQueue pq = new PriorityQueue<>(new FreqComparator()); 37 | for(int key: map.keySet()){ 38 | if(pq.size() < k) 39 | pq.add(new Freq(key, map.get(key))); 40 | else if(map.get(key) > pq.peek().freq){ 41 | pq.remove(); 42 | pq.add(new Freq(key, map.get(key))); 43 | } 44 | } 45 | 46 | LinkedList res = new LinkedList<>(); 47 | while(!pq.isEmpty()) 48 | res.add(pq.remove().e); 49 | return res; 50 | } 51 | 52 | private static void printList(List nums){ 53 | for(Integer num: nums) 54 | System.out.print(num + " "); 55 | System.out.println(); 56 | } 57 | 58 | public static void main(String[] args) { 59 | 60 | int[] nums = {1, 1, 1, 2, 2, 3}; 61 | int k = 2; 62 | printList((new Solution()).topKFrequent(nums, k)); 63 | } 64 | } 65 | --------------------------------------------------------------------------------