Overview
This post is a little different. I’m going to be turning my JavaToRemember Repo into a post so that it’s easier to search. You can find more the old README.md here.
Credits to source article…
Table of content
- String
- Linked List
- Tree
- Graph
- Sorting
- Recursion and iteration
- Dynamic Programming
- Bit Manipulation
- Probability
- Combinations and Permutations
- Files
- Sockets
- Regex
- Formatting
- HashMap
- HashSet
- Deque
1. String
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
"Hello".toCharArray() // ['H', 'e', 'l', 'l', 'o']
Collections.sort(List lst) // sorts a List in place
Arrays.sort(T[] array) // sort an array
Collections.reverse(List lst) // reverses a LIST
Arrays.toString(char[] a) // convert to string
"Hello".charAt(int x) // get a char at the specific index
"Hello".length() // string length
[1,2,3,4,5].length // array size
Character.isLetter('a') // true
Character.isDigit(5) // true
Character.isLetterOrDigit('a') // true
Character.isWhitespace(' ') // true
Character.toLowerCase('A') // 'a'
Character.isUpperCase('a') // false
"abcdef".substring(1, 2) // "b"
"abcdef".substring(1, 5) // "bcde"
"abcdef".substring(3) // "def"
" abcde ".trim() // "abcde"
2. Linked List
The node class which is the “element” of a linked list
1
2
3
4
5
6
7
8
9
class Node {
int val;
Node next;
Node(int x) {
val = x; //value
next = null; //next element
}
}
Stack implementation using the Linked List data structure
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
class Stack{
Node top;
/**
* Default constructor
*/
public Stack(){}
/**
* Method that returns top node
* without removing it
*/
public Node peek(){
if(top != null){
return top;
}
return null;
}
/**
* Method used to remove and
* return top node
*/
public Node pop(){
if(top == null){
return null;
} else {
Node temp = new Node(top.val);
top = top.next;
return temp;
}
}
/**
* Method to add Node
* to the top of the Stack
*/
public void push(Node n){
if(n != null){
n.next = top;
top = n;
}
}
}
Queue implementation using the Linked List data structure
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Queue {
Node first, last;
/**
* Push an element to the back
* of the queue
*/
public void enqueue(Node n){
if(first == null){
first = n;
last = first;
} else {
last.next = n;
last = n;
}
}
/**
* Remove element at the front
*/
public Node dequeue(){
if(first == null){
return null;
} else {
Node temp = new Node(first.val);
first = first.next;
return temp;
}
}
}
3. Tree
The tree class here is for the binary tree
1
2
3
4
5
6
class TreeNode {
int value;
TreeNode parent;
TreeNode left;
TreeNode right;
}
- Binary Search Tree: for all nodes, left children <= current node <= right children
- Balanced vs. Unbalanced: In a balanced tree, the depth of the sibling tree’s can differ max by 1
- Full Binary Tree: every node other than the leaves has two children.
- Perfect Binary Tree: a full binary tree + all leaves same depth + parents have 2 children
- Complete Binary Tree: a binary tree with only last lvl possibly incomplete. We add to lowest lvl and right most
4. Graph
Graphs are used for many things, such as Networking and games.The 2 most famous algorithms for graphs are Depth First Search and Breath First Search
GraphNode
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class GraphNode{
int val;
GraphNode next;
GraphNode[] neighbors;
boolean visited;
/**
* Constructor with value
*/
GraphNode(int x) {
val = x;
}
/**
* Constructor with value
* and with neightbors
*/
GraphNode(int x, GraphNode[] n){
val = x;
neighbors = n;
}
/**
* toString method
*/
public String toString(){
return "value: "+ this.val;
}
}
Breath First Search (live implementation from MIT here)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static Node bfs(Node root, int value) {
// Queue is abstract, use an implementation of queue
Queue<Node> q = new Queue<Node>();
Node returnValue;
q.enqueue(root);
while (!q.isEmpty()) {
Node temp = q.dequeue();
if (temp.value == value) {
returnValue = temp;
break;
}
for (Node adj : temp.adjecent) {
q.enqueue(adj);
}
}
return returnValue;
}
Depth First Search (live implementation from MIT here)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static Node dfs(Node root, int value) {
Stack<Node> s = new Stack<Node>();
Node returnValue;
s.push(root);
while (!q.isEmpty()) {
Node temp = s.pop();
if (temp.value == value) {
returnValue = temp;
break;
}
for (Node adj : temp.adjecent) {
s.push(adj);
}
}
return returnValue;
}
5. Sorting
Here is a table of comparison sorting algorithms and their time complexity
Algorithm | Average Time | Worst Time | Space | Comments |
---|---|---|---|---|
Bubble sort | n^2 | n^2 | 1 | It’s easy to implement |
Insertion sort | n^2 | n^2 | ||
Selection sort | n^2 | n^2 | ||
Heap sort | nlogn | nlogn | ||
Merge sort | nlogn | nlogn | a lot | |
Quick sort | nlogn | n^2 | In practice, is fastest |
Here is a table of algorithms that do not use comparison
Algorithm | Average Time | Worst Time | Space | Comments |
---|---|---|---|---|
Bucket sort | n | n + N | n is the range of keys, N is size of array | |
Radix sort | n | m(n + N) | m is the number of keys |
6. Recursion and Iteration
Recursion is easy to understand and implement. However, it's worse than iteration and can cause stackoverflows
Fibonacci using bad recursion
1
2
3
4
5
6
public static int fib(int n){
if(n <= 1)
return n; //base case
else
return fib(n-1) + fib(n-2); //recursive case
}
Fibonacci using tail recursion
1
2
3
4
5
6
7
8
9
10
11
12
13
public static int fibHelper(int start, int end, int prev, int current){
if(start == end)
return current;
else
return fibHelper(++start, end, current, current + prev);
}
public static int fib(int n){
if(n <= 1)
return n;
else
return fibHelper(1,n,0,1);
}
Fibonacci using iteration
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static int fib(int n) {
if (n <= 1){
return n;
}
int current = 1;
int prev = 0;
int temp = 0;
for (int i = 2; i <= n; i++) {
temp = current + prev; //compute fib at pos n
prev = current; //old current is now prev
current = temp; //current is temp
}
return current;
}
7. Dynamic programming
Dynamic programming is a technique for solving problems with the following properties:
- An instance is solved using the solutions for smaller instances.
- The solution for a smaller instance might be needed multiple times.
- The solutions to smaller instances are stored in a table, so that each smaller instance is solved only once.
- Additional space is used to save time.
The problem of climbing steps perfectly fit those 4 properties. Therefore, it can be solve by using dynamic programming.
1
2
3
4
5
6
7
8
9
10
11
12
public static int[] Steps = new int[100];
public static int f3(int n) {
if (n <= 2)
Steps[n]= n;
if (Steps[n] > 0)
return A[n];
else
Steps[n] = f3(n-1) + f3(n-2); //store results so only calculate once!
return Steps[n];
}
8. Bit Manipulation
Bit operators
Operation name | Java symbol | Example | Result | Explanation |
---|---|---|---|---|
AND | & | 7 & 5 | 5 | 111 & 101 = 101 |
OR | | | 8 | 3 | 11 | 1000 | 0011 = 1011 |
XOR | ^ | 15 ^ 5 | 10 | 1111 ^ 0101 = 1010 |
Right Shift | » | 7 » 1 | 3 | 111 » 1 = 011 |
Not | ~ | ~0 | -1 | ~000 = 111 which is 2’s complement -1 |
9. Probability
There are 50 people in a room, what’s the probability that two people have the same birthday? (Ignoring the fact of leap year, i.e., 365 day every year)
1
2
3
4
5
6
7
8
9
10
public static double caculateProbability(int n){
double x = 1;
for (int i=0; i<n; i++) {
x *= (365.0-i)/365.0;
}
double pro = Math.round((1-x) * 100);
return pro/100;
}
10. Combinations and Permutations
- If the order doesn’t matter, it is a Combination… 1234 same as 4321
- If the order matters, it is a Permutation… 1234 != 2134
Permutation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static void perm(int[] list, int pos){
if (pos == list.length) {
System.out.println( Arrays.toString(list) );
} else {
for(int i=pos; i < list.length; ++i){
swap(list, i, pos);
perm(list, pos + 1);
swap(list, i, pos);
}
}
}
public static final <T> void swap (T[] a, int i, int j) {
T t = a[i];
a[i] = a[j];
a[j] = t;
}
11. Files
Writing to a file.
1
2
3
4
5
6
7
//java8 writing to file
try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(filePath),
StandardCharsets.UTF_8)) {
writer.write("line");
} catch(IOException ioe){
ioe.printStackTrace();
}
Reading from a file
1
2
3
4
5
6
//java8 read all the lines in a file
try (BufferedReader br = Files.newBufferedReader(Paths.get(filePath))) {
list = br.lines().collect(Collectors.toList());
} catch (IOException e) {
e.printStackTrace();
}
12. Sockets
Server that listens for a connection, writes the date and closes connection
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//Server
ServerSocket listener = new ServerSocket(9090);
try {
while (true) {
Socket socket = listener.accept();
try {
ObjectOutputStream out =
new ObjectOutputStream(socket.getOutputStream());
out.writeObject("Hi there");
} finally {
socket.close();
}
}
}
finally {
listener.close();
}
//Client the data is sent through serialization
//to send objects, they must be serializable
Socket s = new Socket(serverAddress, 9090);
try{
ObjectInputStream input = new ObjectInputStream(s.getInputStream());
String answer = (String)input.readObject();
} catch(ClassCastException cce){
cce.printStackTrace();
} finally {
s.close();
}
//On mac, you can open a terminal and write "nc localhost 9090" to connect to server socket
13. Regex
The full documentation can be found here Docs
1
2
3
4
5
6
7
//Long way, that can be reused
Pattern p = Pattern.compile("a*b");
Matcher m = p.matcher("aaaab");
boolean b = m.matches();
//shorthand
boolean b = Pattern.matches("a*b", "aaaaab");
Regular-expression constructs
[abc] | a, b, or c (simple class) |
[^abc] | Any character except a, b, or c (negation) |
[a-zA-Z] | a through z or A through Z, inclusive (range) |
[a-d[m-p]] | a through d, or m through p: [a-dm-p] (union) |
[a-z&&[def]] | d, e, or f (intersection) |
[a-z&&[^bc]] | a through z, except for b and c: [ad-z] (subtraction) |
[a-z&&[^m-p]] | a through z, and not m through p: [a-lq-z](subtraction) |
Predefined character classes
. | Any character (may or may not match line terminators) |
\d | A digit: [0-9] |
\D | A non-digit: [^0-9] |
\s | A whitespace character: [ \t\n\x0B\f\r] |
\S | A non-whitespace character: [^\s] |
\w | A word character: [a-zA-Z_0-9] |
\W | A non-word character: [^\w] |
Greedy quantifiers
X? | X, once or not at all |
X* | X, zero or more times |
X+ | X, one or more times |
X{n} | X, exactly n times |
X{n,} | X, at least n times |
X{n,m} | X, at least n but not more than m times |
14. Formatting
Full article can be found here.
Strings
Code | Description |
%s | will print the string as it is. |
%15s | will print the string as it is. If the string has less than 15 characters, the output will be padded on the left. |
%-6s | will print the string as it is. If the string has less than 6 characters, the output will be padded on the right. |
%.8s | will print maximum 8 characters of the string. |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Padding left
System.out.printf("%10s %10s\n", "hello", "world");
// Padding right
System.out.printf("%-10s %-10s\n", "hello", "world");
// As is
System.out.printf("%s %s\n", "hello", "world");
// Max 2 characters
System.out.printf("%.2s %.2s\n", "hello", "world");
/*
hello world
hello world
hello world
he wo
*/
Integers
Code | Description |
%d | will print the integer as it is. |
%6d | will print the integer as it is. If the number of digits is less than 6, the output will be padded on the left. |
%-6d | will print the integer as it is. If the number of digits is less than 6, the output will be padded on the right. |
%06d | will print the integer as it is. If the number of digits is less than 6, the output will be padded on the left with zeroes. |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Padding left
System.out.printf("%10d %10d\n", 12345, 54321);
// Padding right
System.out.printf("%-10d %-10d\n", 12345, 54321);
// As is
System.out.printf("%d %d\n", 12345, 54321);
// fill rest of 10 digits with 0s
System.out.printf("%010d %010d\n", 12345, 54321);
/*
12345 54321
12345 54321
12345 54321
0000012345 0000054321
*/
Floats
Code | Description |
%f | will print the number as it is. |
%15f | will print the number as it is. If the number has less than 15 digits, the output will be padded on the left. |
%.8f | will print maximum 8 decimal digits of the number. |
%9.4f | will print maximum 4 decimal digits of the number. The output will occupy 9 characters at least. If the number of digits is not enough, it will be padded |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Padding left
System.out.printf("%14f %14f\n", 123.456789, 987.654321);
// Padding right
System.out.printf("%-14f %-14f\n", 123.456789, 987.654321);
// As is
System.out.printf("%f %f\n", 123.456789, 987.654321);
// 3 digit Precision + left padding
System.out.printf("%14.3f %14.3f\n", 123.456789, 987.654321);
/*
123.456789 987.654321
123.456789 987.654321
123.456789 987.654321
123.457 987.654
*/
15. HashMap
HashMaps & HashTables allow inserts, deletes and gets at O(1). HashTables are synchronized while HashMaps are not. HashTables do not allow null keys or values. HashMaps allows 1 null key and unlimited null values. The synchronized HashMap is the ConcurrentHashMap<Key,Value> which is in java.util.concurrent. Source: here
1
2
3
4
5
6
7
8
9
10
11
Map<String, Integer> map = new HashMap<>();
map.put("a", 1); // { a:1 }
map.put("b", 2); // { a:1, b:2 }
map.put("c", 3); // { a:1, b:2, c:3 }
map.get("a"); // 1
map.containsKey("d"); // false
map.values(); // [1, 2, 3]
map.keySet(); // ["a", "b", "c"]
map.remove("a"); // { b:2, c:3 }
map.clear(); // {}
16. HashSet
A HashSet is a dictionary that only stores keys. It doesn’t allow for duplicates and only stores keys.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Set<Integer> set = new HashSet<>();
set.add(1); // { 1 }
set.add(2); // { 1, 2 }
set.add(3); // { 1, 2, 3 }
set.contains(5); // false
set.contains(2); // true
set.remove(2); // { 1, 3 }
for(int val: set) {
System.out.println(val);
}
// 1
// 3
List<Integer> list = new ArrayList<>(set); // [1,3]
set.clear(); // {}
17. Deque
Deques implement the interfaces of both Stacks and Queues. They are great for both.
1
2
3
4
5
6
7
8
9
10
11
12
13
Deque<Integer> deque = new ArrayDeque<>();
deque.add(5); // [5]
deque.addFirst(2); // [2,5]
deque.addLast(3); // [2,5,3]
deque.getFirst(); // 2
deque.getLast(); // 3
deque.removeFirst(); // 2 [5,3]
deque.removeLast(); // 3 [5]
int[] array = new int[deque.size()]; // [0]
deque.toArray(array);