set = new HashSet<>();
19 | for (char c : s.toCharArray()) {
20 | if (c == ' ') continue;
21 | if (set.contains(c)) set.remove(c);
22 | else set.add(c);
23 | }
24 | return set.size() < 2;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/arraystring/_01_05_OneAway.java:
--------------------------------------------------------------------------------
1 | package arraystring;
2 |
3 | /**
4 | * There are three types of edits that can be performed on strings:
5 | * insert a character, remove a character, or replace a character.
6 | * Given two strings, write a function to check if they are one edit (or zero edits) away.
7 | *
8 | * EXAMPLE
9 | * pale, ple -> true
10 | * pales, pale -> true
11 | * pale, bale -> true
12 | * pale, bake -> false
13 | */
14 | class _01_05_OneAway {
15 | boolean isOneAway(String a, String b) {
16 | if (a.length() == b.length()) {
17 | return oneReplace(a, b);
18 | } else if (a.length() - b.length() == 1) {
19 | return oneInsertion(a, b);
20 | } else if (b.length() - a.length() == 1) {
21 | return oneInsertion(b, a);
22 | } else {
23 | return false;
24 | }
25 | }
26 |
27 | private boolean oneInsertion(String longStr, String shortStr) {
28 | boolean insert = false;
29 | for (int i = 0, j = 0; i < shortStr.length(); i++, j++) {
30 | if (shortStr.charAt(i) != longStr.charAt(j)) {
31 | if (insert) return false;
32 | insert = true;
33 | i--;
34 | }
35 | }
36 |
37 | return true;
38 | }
39 |
40 | private boolean oneReplace(String a, String b) {
41 | boolean replace = false;
42 | for (int i = 0; i < a.length(); i++) {
43 | if (a.charAt(i) != b.charAt(i)) {
44 | if (replace) return false;
45 | replace = true;
46 | }
47 | }
48 | return true;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/arraystring/_01_06_StringCompression.java:
--------------------------------------------------------------------------------
1 | package arraystring;
2 |
3 | /**
4 | * Implement a method to perform basic string compression using the counts of repeated characters.
5 | * For example, the string aabcccccaaa would become a2blc5a3.
6 | * If the "compressed" string would not become smaller than the original string, your method should return
7 | * the original string. You can assume the string has only uppercase and lowercase letters (a - z).
8 | */
9 | class _01_06_StringCompression {
10 | String compress(String s) {
11 | StringBuilder sb = new StringBuilder();
12 | int count = 0;
13 | for (int i = 0; i < s.length(); i++) {
14 | count++;
15 | if (i == s.length() - 1 || s.charAt(i) != s.charAt(i + 1)) {
16 | sb.append(count).append(s.charAt(i));
17 | count = 0;
18 | }
19 | }
20 | return sb.length() < s.length() ? sb.toString() : s;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/arraystring/_01_07_RotateMatrix.java:
--------------------------------------------------------------------------------
1 | package arraystring;
2 |
3 | /**
4 | * Given an image represented by an NxN matrix, where each pixel in the image is 4 bytes,
5 | * write a method to rotate the image by 90 degrees. Can you do this in place?
6 | */
7 | class _01_07_RotateMatrix {
8 | int[][] rotate(int[][] m) {
9 | int n = m.length;
10 | swapRow(m, n);
11 | transpose(m, n);
12 | return m;
13 | }
14 |
15 | private void transpose(int[][] m, int n) {
16 | for (int i = 0; i < n; i++) {
17 | for (int j = i + 1; j < n; j++) {
18 | int tmp = m[i][j];
19 | m[i][j] = m[j][i];
20 | m[j][i] = tmp;
21 | }
22 | }
23 | }
24 |
25 | private void swapRow(int[][] m, int n) {
26 | for (int start = 0, end = n - 1; start < end; start++, end--) {
27 | int[] tmp = m[start];
28 | m[start] = m[end];
29 | m[end] = tmp;
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/arraystring/_01_08_ZeroMatrix.java:
--------------------------------------------------------------------------------
1 | package arraystring;
2 |
3 | /**
4 | * Write an algorithm such that if an element in an MxN matrix is 0, its entire row and column are set to 0.
5 | */
6 | class _01_08_ZeroMatrix {
7 | int[][] zero(int[][] matrix) {
8 | int m = matrix.length;
9 | if (m == 0) return matrix;
10 | int n = matrix[0].length;
11 | if (n == 0) return matrix;
12 |
13 | boolean hasZeroInFirstRow = findZeroInFirstRow(matrix[0], n);
14 |
15 | boolean hasZeroInFirstCol = findZeroInFirstCol(matrix, m);
16 |
17 | detectZeroRowCol(matrix, m, n);
18 |
19 | zeroRows(matrix, m, n);
20 |
21 | zeroCols(matrix, m, n);
22 |
23 | if (hasZeroInFirstRow) {
24 | zeroFirstRow(matrix, n);
25 | }
26 |
27 | if (hasZeroInFirstCol) {
28 | zeroFirstCol(matrix, m);
29 | }
30 |
31 | return matrix;
32 |
33 | }
34 |
35 | private void zeroFirstCol(int[][] matrix, int m) {
36 | for (int i = 0; i < m; i++) {
37 | matrix[i][0] = 0;
38 | }
39 | }
40 |
41 | private void zeroFirstRow(int[][] matrix, int n) {
42 | for (int j = 0; j < n; j++) {
43 | matrix[0][j] = 0;
44 | }
45 | }
46 |
47 | private void zeroCols(int[][] matrix, int m, int n) {
48 | for (int j = 1; j < n; j++) {
49 | if (matrix[0][j] == 0) {
50 | for (int i = 0; i < m; i++) {
51 | matrix[i][j] = 0;
52 | }
53 | }
54 | }
55 | }
56 |
57 | private void zeroRows(int[][] matrix, int m, int n) {
58 | for (int i = 1; i < m; i++) {
59 | if (matrix[i][0] == 0) {
60 | for (int j = 0; j < n; j++) {
61 | matrix[i][j] = 0;
62 | }
63 | }
64 | }
65 | }
66 |
67 | private void detectZeroRowCol(int[][] matrix, int m, int n) {
68 | for (int i = 0; i < m; i++) {
69 | for (int j = 0; j < n; j++) {
70 | if (matrix[i][j] == 0) {
71 | matrix[i][0] = 0;
72 | matrix[0][j] = 0;
73 | }
74 | }
75 | }
76 | }
77 |
78 | private boolean findZeroInFirstCol(int[][] matrix, int m) {
79 | boolean hasZeroInFirstCol = false;
80 | for (int i = 0; i < m; i++) {
81 | if (matrix[i][0] == 0) hasZeroInFirstCol = true;
82 | }
83 | return hasZeroInFirstCol;
84 | }
85 |
86 | private boolean findZeroInFirstRow(int[] matrix, int n) {
87 | boolean hasZeroInFirstRow = false;
88 | for (int j = 0; j < n; j++) {
89 | if (matrix[j] == 0) hasZeroInFirstRow = true;
90 | }
91 | return hasZeroInFirstRow;
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/main/java/arraystring/_01_09_StringRotation.java:
--------------------------------------------------------------------------------
1 | package arraystring;
2 |
3 | /**
4 | * Assume you have a method isSubstring which checks if one word is a substring of another.
5 | * Given two strings, sl and s2, write code to check if s2 is a rotation of s1
6 | * using only one call to isSubstring (e.g.,"waterbottle" is a rotation of"erbottlewat").
7 | */
8 | class _01_09_StringRotation {
9 | boolean rotated(String original, String result) {
10 | return original.length() == result.length() && isSubstring((original + original), result);
11 | }
12 |
13 | private boolean isSubstring(String complete, String sub) {
14 | return complete.contains(sub);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/bitmanipulation/_05_01_Insertion.java:
--------------------------------------------------------------------------------
1 | package bitmanipulation;
2 |
3 | /**
4 | * You are given two 32-bit numbers, N and M, and two bit positions, i and j.
5 | * Write a method to insert M into N such that M starts at bit j and ends at bit i.
6 | * You can assume that the bits j through i have enough space to fit all of M.
7 | * That is, if M = 10011, you can assume that there are at least 5 bits between j and i.
8 | * You would not, for example, have j = 3 and i = 2, because M could not fully fit between bit 3 and bit 2.
9 | *
10 | * EXAMPLE
11 | * Input: N 10000000000, M 10011, i 2, j 6
12 | * Output:N = 10001001100
13 | */
14 | class _05_01_Insertion {
15 |
16 | int insert(int n, int m, int i, int j) {
17 | int allOnes = -1;
18 | int left = allOnes << (j + 1);
19 | int right = (1 << i) - 1;
20 | int mask = left | right;
21 | int shiftedM = m << i;
22 | int clearedN = n & mask;
23 | return shiftedM | clearedN;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/bitmanipulation/_05_02_BinaryToString.java:
--------------------------------------------------------------------------------
1 | package bitmanipulation;
2 |
3 | /**
4 | * Given a real number between O and 1 (e.g., 0.72) that is passed in as a double, print the binary representation.
5 | * If the number cannot be represented accurately in binary with at most 32 characters, print "ERROR:'
6 | */
7 | class _05_02_BinaryToString {
8 | String print(double num) {
9 | if (num <= 0 || num >= 1) return "ERROR";
10 | StringBuilder sb = new StringBuilder();
11 | sb.append(".");
12 | for (int i = 0; i < 32; i++) {
13 | if (num == 0) return sb.toString();
14 | num *= 2;
15 | if (num >= 1.0) {
16 | sb.append('1');
17 | num -= 1;
18 | } else {
19 | sb.append('0');
20 | }
21 | }
22 | return "ERROR";
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/bitmanipulation/_05_03_FlipBitToWin.java:
--------------------------------------------------------------------------------
1 | package bitmanipulation;
2 |
3 | /**
4 | * You have an integer and you can flip exactly one bit from a 0 to a 1.
5 | * Write code to find the length of the longest sequence of 1s you could create.
6 | *
7 | * EXAMPLE
8 | * Input: 1775 (or: 11011101111)
9 | * Output: 8
10 | */
11 | class _05_03_FlipBitToWin {
12 | int flip(int n) {
13 | if (n == -1) return 32;
14 | int pre = 0;
15 | int cur = 0;
16 | int max = 1;
17 | while (n != 0) {
18 | if ((n & 1) == 1) {
19 | cur++;
20 | } else {
21 | pre = (n & 2) == 0 ? 0 : cur;
22 | cur = 0;
23 | }
24 | max = Math.max(max, pre + cur + 1);
25 | n >>>= 1;
26 | }
27 | return max;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/bitmanipulation/_05_04_NextBiggerNumber.java:
--------------------------------------------------------------------------------
1 | package bitmanipulation;
2 |
3 | /**
4 | * Given a positive integer,
5 | * print the next largest number that
6 | * have the same number of 1 bits in their binary representation.
7 | */
8 | class _05_04_NextBiggerNumber {
9 |
10 | int nextBigger(int n) {
11 | if (n <= 0) return -1;
12 |
13 | int tmp = n;
14 | int zeros = 0;
15 | int ones = 0;
16 | while (tmp != 0 && (tmp & 1) == 0) {
17 | zeros++;
18 | tmp >>= 1;
19 | }
20 | while ((tmp & 1) == 1) {
21 | ones++;
22 | tmp >>= 1;
23 | }
24 |
25 | if (zeros + ones == 31) return -1;
26 |
27 | //flip zero to one
28 | n = n | 1 << (zeros + ones);
29 |
30 | //clear right part
31 | n = n & ~((1 << (zeros + ones)) - 1);
32 |
33 | //add ones
34 | n = n | ((1 << (ones - 1)) - 1);
35 |
36 | return n;
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/bitmanipulation/_05_04_NextSmallerNumber.java:
--------------------------------------------------------------------------------
1 | package bitmanipulation;
2 |
3 | /**
4 | * Given a positive integer,
5 | * print the next smallest number that
6 | * have the same number of 1 bits in their binary representation.
7 | */
8 | class _05_04_NextSmallerNumber {
9 |
10 | int nextSmaller(int n) {
11 | if (n <= 0) return -1;
12 |
13 | int tmp = n;
14 | int zeros = 0;
15 | int ones = 0;
16 | while ((tmp & 1) == 1) {
17 | ones++;
18 | tmp >>= 1;
19 | }
20 |
21 | while (tmp > 0 && (tmp & 1) == 0) {
22 | zeros++;
23 | tmp >>= 1;
24 | }
25 |
26 | if (zeros == 0) return -1;
27 |
28 | //clear right part
29 | n = n & ~((1 << (zeros + ones + 1)) - 1);
30 |
31 | //add ones
32 | n = n | (((1 << (ones + 1)) - 1) << (zeros - 1));
33 |
34 | return n;
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/bitmanipulation/_05_05_Debugger.java:
--------------------------------------------------------------------------------
1 | package bitmanipulation;
2 |
3 | /**
4 | * Explain what the following code does
5 | */
6 | public class _05_05_Debugger {
7 |
8 | // n & (n - 1) clears the least significant bit, if nothing remains. it means there is only is one 1.
9 | // therefore it's a power of 2
10 | boolean debug(int n) {
11 | return (n & (n - 1)) == 0;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/bitmanipulation/_05_06_Conversion.java:
--------------------------------------------------------------------------------
1 | package bitmanipulation;
2 |
3 | /**
4 | * Write a function to determine the number of bits you would need to flip to convert
5 | * integer A to integer B.
6 | *
7 | * EXAMPLE
8 | * Input: 29 (or: 11101), 15 (or: 01111)
9 | * Output: 2
10 | */
11 | public class _05_06_Conversion {
12 | int convert(int a, int b) {
13 | int c = a ^ b;
14 | int ones = 0;
15 | while (c > 0) {
16 | ones++;
17 | c &= c - 1;
18 | }
19 | return ones;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/bitmanipulation/_05_07_PairwiseSwap.java:
--------------------------------------------------------------------------------
1 | package bitmanipulation;
2 |
3 | /**
4 | * Write a program to swap odd and even bits in an integer with as few instructions as
5 | * possible (e.g., bit 0 and bit 1 are swapped, bit 2 and bit 3 are swapped, and so on).
6 | */
7 | class _05_07_PairwiseSwap {
8 | int swap(int n) {
9 | return ((0xaaaa_aaaa & n) >>> 1) | ((0x5555_5555 & n) << 1);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/java/bitmanipulation/_05_08_DrawLine.java:
--------------------------------------------------------------------------------
1 | package bitmanipulation;
2 |
3 | /**
4 | * A monochrome screen is stored as a single array of bytes, allowing eight consecutive pixels to be stored in one byte.
5 | *
6 | * The screen has width w, where w is divisible by 8 (that is, no byte will be split across rows).
7 | * The height of the screen, of course, can be derived from the length of the array and the width.
8 | *
9 | * Implement a function that draws a horizontal line from (x1, y) to ( x2, y).
10 | *
11 | * for example, if screen has a width 16 and a height 2. | encoded as 0 and - as 1
12 | * | | | | | | | | | | | | | | | |
13 | * | | | | | | | | | | | | | | | |
14 | *
15 | * drawing a line from (2, 1) to (13, 1) gives the following result
16 | * | | | | | | | | | | | | | | | |
17 | * | | - - - - - - - - - - - - | |
18 | */
19 | class _05_08_DrawLine {
20 | byte[] drawLine(byte[] screen, int width, int x1, int x2, int y) {
21 | if (x2 < x1) throw new IllegalArgumentException("end must not be less than start");
22 | int startByte = x1 / 8;
23 | int endByte = x2 / 8;
24 |
25 | int row = width / 8 * y;
26 |
27 | for (int i = startByte + 1; i <= endByte - 1; i++) {
28 | screen[row + i] = (byte) 0xff;
29 | }
30 |
31 | int startIndex = x1 % 8;
32 | int endIndex = x2 % 8;
33 |
34 | if (startByte == endByte) {
35 | set(screen, row + startByte, startIndex, endIndex);
36 | } else {
37 | set(screen, row + startByte, startIndex, 7);
38 | set(screen, row + endByte, 0, endIndex);
39 | }
40 | return screen;
41 | }
42 |
43 | private void set(byte[] screen, int i, int start, int end) {
44 | screen[i] |= (byte) ((0xff >> start) & ~(0xff >> (end + 1)));
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/linkedlist/LinkedListNode.java:
--------------------------------------------------------------------------------
1 | package linkedlist;
2 |
3 | import java.util.Objects;
4 |
5 | public class LinkedListNode {
6 |
7 | int val;
8 | LinkedListNode next;
9 |
10 | LinkedListNode(int val) {
11 | this.val = val;
12 | }
13 |
14 | static LinkedListNode empty() {
15 | return null;
16 | }
17 |
18 | static LinkedListNode of(int... list) {
19 | LinkedListNode pre = null;
20 | LinkedListNode head = null;
21 | for (int val : list) {
22 | if (pre == null) {
23 | head = new LinkedListNode(val);
24 | pre = head;
25 | } else {
26 | pre.next = new LinkedListNode(val);
27 | pre = pre.next;
28 | }
29 | }
30 | return head;
31 | }
32 |
33 | @Override
34 | public boolean equals(Object o) {
35 | if (this == o) return true;
36 | if (o == null || getClass() != o.getClass()) return false;
37 | LinkedListNode that = (LinkedListNode) o;
38 | return val == that.val &&
39 | Objects.equals(next, that.next);
40 | }
41 |
42 | @Override
43 | public String toString() {
44 | return "LinkedListNode{" +
45 | "val=" + val +
46 | ", next=" + next +
47 | '}';
48 | }
49 |
50 | @Override
51 | public int hashCode() {
52 | return Objects.hash(val, next);
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/src/main/java/linkedlist/_02_01_RemoveDups.java:
--------------------------------------------------------------------------------
1 | package linkedlist;
2 |
3 | import java.util.HashSet;
4 | import java.util.Set;
5 |
6 | /**
7 | * Remove Dups!
8 | * Write code to remove duplicates from an unsorted linked list.
9 | */
10 | class _02_01_RemoveDups {
11 |
12 | // time o(n)
13 | // space o(n)
14 | LinkedListNode removeDups(LinkedListNode head) {
15 | Set set = new HashSet<>();
16 | LinkedListNode pre = null;
17 | LinkedListNode next = head;
18 | while (next != null) {
19 | if (set.contains(next.val)) {
20 | pre.next = next.next;
21 | } else {
22 | set.add(next.val);
23 | pre = next;
24 | }
25 | next = next.next;
26 | }
27 | return head;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/linkedlist/_02_02_ReturnKthToLast.java:
--------------------------------------------------------------------------------
1 | package linkedlist;
2 |
3 | /**
4 | * Implement an algorithm to find the kth to last element of a singly linked list
5 | */
6 | class _02_02_ReturnKthToLast {
7 |
8 | // time o(n)
9 | // space o(1)
10 | LinkedListNode kthToLast(LinkedListNode head, int k) {
11 | LinkedListNode kth = head;
12 | LinkedListNode runner = head;
13 | int dist = 0;
14 | while (runner.next != null) {
15 | if (dist == k) {
16 | runner = runner.next;
17 | kth = kth.next;
18 | } else {
19 | runner = runner.next;
20 | dist++;
21 | }
22 | }
23 | return dist == k ? kth : null;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/linkedlist/_02_03_DeleteMiddleNode.java:
--------------------------------------------------------------------------------
1 | package linkedlist;
2 |
3 | /**
4 | * Implement an algorithm to delete a node in the
5 | * middle(i.e., any node but the first and last node, not necessarily the exact middle)
6 | * of a singly linked list, given only access to that node.
7 | */
8 | class _02_03_DeleteMiddleNode {
9 |
10 | // time o(1)
11 | // space o(1)
12 | boolean deleteMiddleNode(LinkedListNode node) {
13 | if (node == null || node.next == null) return false;
14 | LinkedListNode next = node.next;
15 | node.val = next.val;
16 | node.next = next.next;
17 | return true;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/linkedlist/_02_04_Partition.java:
--------------------------------------------------------------------------------
1 | package linkedlist;
2 |
3 | /**
4 | * Partition: Write code to partition a linked list around a value x,
5 | * such that all nodes less than x come before all nodes greater than or equal to x.
6 | * If x is contained within the list, the values of x only need to be after the elements less than x (see below).
7 | * The partition element x can appear anywhere in the "right partition";
8 | * it does not need to appear between the left and right partitions.
9 | * EXAMPLE
10 | * Input: 3 -> 5 -> 8 -> 5 -> 10 -> 2 -> 1[partition=5]
11 | * Output: 3 -> 1 -> 2 -> 10 -> 5 -> 5 -> 8
12 | */
13 | class _02_04_Partition {
14 |
15 | LinkedListNode partition(LinkedListNode head, int x) {
16 | if (head == null) return null;
17 | LinkedListNode pre = null;
18 | LinkedListNode cur = head;
19 | while (cur != null) {
20 | if (cur.val < x && pre != null) {
21 | pre.next = cur.next;
22 | cur.next = head;
23 | head = cur;
24 | cur = pre.next;
25 | } else {
26 | pre = cur;
27 | cur = cur.next;
28 | }
29 | }
30 | return head;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/linkedlist/_02_05_SumList.java:
--------------------------------------------------------------------------------
1 | package linkedlist;
2 |
3 | /**
4 | * Sum Lists: You have two numbers represented by a linked list,
5 | * where each node contains a single digit.
6 | * The digits are stored in normal order, such that the 1 's digit is at the tail of the list.
7 | * Write a function that adds the two numbers and returns the sum as a linked list.
8 | *
9 | * EXAMPLE
10 | * Input:(7-> 1 -> 6) + (5 -> 9 -> 2).That is, 716 + 592.
11 | * Output:1 -> 4 -> 0 -> 8.That is, 1408.
12 | */
13 | class _02_05_SumList {
14 |
15 | LinkedListNode sum(LinkedListNode l1, LinkedListNode l2) {
16 | int length1 = len(l1);
17 | int length2 = len(l2);
18 | l1 = pad(l1, length2 - length1);
19 | l2 = pad(l2, length1 - length2);
20 | PartialSum partial = sumRec(l1, l2);
21 | if (partial.carry == 0) return partial.head;
22 | LinkedListNode head = new LinkedListNode(1);
23 | head.next = partial.head;
24 | return head;
25 | }
26 |
27 | private PartialSum sumRec(LinkedListNode l1, LinkedListNode l2) {
28 | if (l1 == null || l2 == null) {
29 | return new PartialSum();
30 | }
31 | PartialSum partial = sumRec(l1.next, l2.next);
32 |
33 | int sum = l1.val + l2.val + partial.carry;
34 | LinkedListNode n = new LinkedListNode(sum % 10);
35 | n.next = partial.head;
36 | partial.head = n;
37 | partial.carry = sum / 10;
38 | return partial;
39 | }
40 |
41 | private int len(LinkedListNode node) {
42 | int l = 0;
43 | while (node != null) {
44 | node = node.next;
45 | l++;
46 | }
47 | return l;
48 | }
49 |
50 | private LinkedListNode pad(LinkedListNode head, int padding) {
51 | for (int i = 0; i < padding; i++) {
52 | LinkedListNode n = new LinkedListNode(0);
53 | n.next = head;
54 | head = n;
55 | }
56 | return head;
57 | }
58 |
59 | static class PartialSum {
60 | LinkedListNode head;
61 | int carry;
62 | }
63 |
64 |
65 | }
66 |
--------------------------------------------------------------------------------
/src/main/java/linkedlist/_02_05_SumListReverse.java:
--------------------------------------------------------------------------------
1 | package linkedlist;
2 |
3 | /**
4 | * Sum Lists: You have two numbers represented by a linked list,
5 | * where each node contains a single digit.
6 | * The digits are stored in reverse order, such that the 1 's digit is at the head of the list.
7 | * Write a function that adds the two numbers and returns the sum as a linked list.
8 | *
9 | * EXAMPLE
10 | * Input:(7-> 1 -> 6) + (5 -> 9 -> 2).That is,617 + 295.
11 | * Output:2 -> 1 -> 9.That is,912.
12 | */
13 | class _02_05_SumListReverse {
14 | LinkedListNode sum(LinkedListNode l1, LinkedListNode l2) {
15 | LinkedListNode head = null;
16 | LinkedListNode tail = null;
17 | int carry = 0;
18 | while (l1 != null || l2 != null) {
19 | LinkedListNode n = new LinkedListNode(0);
20 | int sum = carry;
21 | if (l1 != null) {
22 | sum += l1.val;
23 | l1 = l1.next;
24 | }
25 |
26 | if (l2 != null) {
27 | sum += l2.val;
28 | l2 = l2.next;
29 | }
30 |
31 | n.val = sum % 10;
32 | carry = sum / 10;
33 |
34 | if (head == null) {
35 | head = n;
36 | tail = n;
37 | } else {
38 | tail.next = n;
39 | tail = n;
40 | }
41 | }
42 | if (carry == 1) tail.next = new LinkedListNode(1);
43 | return head;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/linkedlist/_02_06_Palindrome.java:
--------------------------------------------------------------------------------
1 | package linkedlist;
2 |
3 | import java.util.Stack;
4 |
5 | /**
6 | * Palindrome: Implement a function to check if a linked list is a palindrome.
7 | */
8 | class _02_06_Palindrome {
9 |
10 | boolean isPalindrome(LinkedListNode head) {
11 | if (head == null) return true;
12 | Stack stack = new Stack<>();
13 | LinkedListNode cur = head;
14 | while (cur != null) {
15 | stack.push(cur.val);
16 | cur = cur.next;
17 | }
18 |
19 | int half = stack.size() / 2;
20 | while (half >= 0) {
21 | int val = stack.pop();
22 | if (val != head.val) return false;
23 | head = head.next;
24 | half--;
25 | }
26 | return true;
27 | }
28 |
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/linkedlist/_02_07_Intersection.java:
--------------------------------------------------------------------------------
1 | package linkedlist;
2 |
3 | /**
4 | * Intersection: Given two (singly) linked lists, determine if the two lists intersect.
5 | * Return the intersecting node. Note that the intersection is de ned based on reference, not value.
6 | * That is, if the kth node of the first linked list is the exact same node (by reference)
7 | * as the jth node of the second linked list, then they are intersecting.
8 | */
9 | class _02_07_Intersection {
10 |
11 | boolean intersects(LinkedListNode l1, LinkedListNode l2) {
12 | if (l1 == null || l2 == null) return false;
13 | LinkedListNode r1 = l1;
14 | LinkedListNode r2 = l2;
15 | boolean switched1 = false;
16 | boolean switched2 = false;
17 | while (r1 != null || r2 != null) {
18 | if (r1 == r2) return true;
19 | if (r1 == null) {
20 | if (switched1) return false;
21 | r1 = l2;
22 | switched1 = true;
23 | } else {
24 | r1 = r1.next;
25 | }
26 |
27 | if (r2 == null) {
28 | if (switched2) return false;
29 | r2 = l1;
30 | switched2 = true;
31 | } else {
32 | r2 = r2.next;
33 | }
34 | }
35 | return false;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/linkedlist/_02_08_LoopDetection.java:
--------------------------------------------------------------------------------
1 | package linkedlist;
2 |
3 | /**
4 | * Loop Detection: Given a circular linked list, implement an algorithm that returns the node at the
5 | * beginning of the loop.
6 | *
7 | * DEFINITION
8 | * Circular linked list: A (corrupt) linked list in which a node's next pointer points to an earlier node, so as to make a loop in the linked list.
9 | *
10 | * EXAMPLE
11 | * Input: A -> B -> C -> D -> E -> C[the same C as earlier]
12 | * Output: C
13 | */
14 | class _02_08_LoopDetection {
15 |
16 | LinkedListNode detect(LinkedListNode head) {
17 | LinkedListNode runner = head;
18 | LinkedListNode walker = head;
19 | while (runner != null && runner.next != null) {
20 | runner = runner.next.next;
21 | walker = walker.next;
22 | if (runner == walker) break;
23 | }
24 | if (runner == null || runner.next == null) return null;
25 |
26 | walker = head;
27 | while (runner != walker) {
28 | runner = runner.next;
29 | walker = walker.next;
30 | }
31 | return runner;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/mathlogic/_06_01_TheHeavyPill.java:
--------------------------------------------------------------------------------
1 | package mathlogic;
2 |
3 | /**
4 | * You have 20 bottles of pills. 19 bottles have 1.0 gram pills, but one has pills of weight 1.1 grams.
5 | * Given a scale that provides an exact measurement, how would you find the heavy bottle?
6 | * You can only use the scale once.
7 | */
8 | public class _06_01_TheHeavyPill {
9 |
10 | /**
11 | * pick one pill form the #1 bottle and two pills from #2 bottle and n pills from #n bottle
12 | * according the extra contribution, we can't identify the bottle with heavy pills
13 | * weight = normalWeight + extraWeight where normalWeight = (1 + 2 + ... + 20) = 20 * ( 1 + 20)/2 = 210
14 | * #bottle = (weight - 210) / 0.1
15 | *
16 | * note that we need to assume there are enough pills in the bottles
17 | */
18 | void solution() {
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/moderate/_16_01_NumberSwapper.java:
--------------------------------------------------------------------------------
1 | package moderate;
2 |
3 | /**
4 | * Write a function to swap a number in place (that is, without temporary variables).
5 | */
6 | class _16_01_NumberSwapper {
7 |
8 | void swap(int[] ab) {
9 | ab[0] = ab[0] ^ ab[1];
10 | ab[1] = ab[0] ^ ab[1];
11 | ab[0] = ab[0] ^ ab[1];
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/moderate/_16_06_SmallestDifference.java:
--------------------------------------------------------------------------------
1 | package moderate;
2 |
3 | import java.util.Arrays;
4 |
5 | /**
6 | * Given two arrays of integers, compute the pair of values (one value in each array)
7 | * with the smallest (non-negative) difference. Return the difference.
8 | *
9 | * EXAMPLE
10 | * Input: {1, 3, 15, 11, 2}, {23, 127,235, 19, 8}
11 | * Output: 3. That is, the pair (11, 8).
12 | */
13 | public class _16_06_SmallestDifference {
14 |
15 | int findSmallestDiff(int[] a1, int[] a2) {
16 | int[] small = a1.length < a2.length ? a1 : a2;
17 | int[] big = small == a1 ? a2 : a1;
18 | Arrays.sort(small);
19 | int diff = Integer.MAX_VALUE;
20 | for (int i : big) {
21 | int p = Arrays.binarySearch(small, i);
22 | if (p < 0) {
23 | int insertion = -p - 1;
24 | if (insertion > 0) {
25 | diff = Math.min(diff, i - small[insertion - 1]);
26 | }
27 |
28 | if (insertion < small.length) {
29 | diff = Math.min(diff, small[insertion] - i);
30 | }
31 | }
32 | }
33 | return diff;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/recursivedp/_08_01_TripleStep.java:
--------------------------------------------------------------------------------
1 | package recursivedp;
2 |
3 | /**
4 | * A child is running up a staircase with n steps and can hop either 1 step, 2 steps, or 3 steps at a time.
5 | * Implement a method to count how many possible ways the child can run up the stairs.
6 | */
7 | class _08_01_TripleStep {
8 |
9 | //time o(n) space o(1)
10 | int countWays(int steps) {
11 | if (steps == 0) return 1;
12 | else if (steps == 1) return 1;
13 | else if (steps == 2) return 2;
14 | else if (steps == 3) return 4;
15 | int a = 1;
16 | int b = 2;
17 | int c = 4;
18 | int ways = 0;
19 | for (int i = 4; i <= steps; i++) {
20 | ways = a + b + c;
21 | a = b;
22 | b = c;
23 | c = ways;
24 | }
25 | return ways;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/recursivedp/_08_02_RobotInAGrid.java:
--------------------------------------------------------------------------------
1 | package recursivedp;
2 |
3 | import java.awt.*;
4 | import java.util.*;
5 | import java.util.List;
6 |
7 | /**
8 | * Imagine a robot sitting on the upper left corner of grid with r rows and c columns.
9 | * The robot can only move in two directions, right and down, but certain cells are "off limits"
10 | * such that the robot cannot step on them. Design an algorithm to find a path for the robot
11 | * from the top left to the bottom right.
12 | */
13 | class _08_02_RobotInAGrid {
14 | List findPath(boolean[][] grid) {
15 | if (grid == null || grid.length == 0) return Collections.emptyList();
16 | int rows = grid.length - 1;
17 | int cols = grid[0].length - 1;
18 | List path = new ArrayList<>();
19 | Set failed = new HashSet<>();
20 | getPath(grid, rows, cols, path, failed);
21 | return path;
22 | }
23 |
24 | private boolean getPath(boolean[][] grid, int r, int c, List path, Set failed) {
25 | if (r < 0 || c < 0 || !grid[r][c]) {
26 | return false;
27 | }
28 | Point p = new Point(r, c);
29 |
30 | if (failed.contains(p)) return false;
31 |
32 | boolean isOrigin = (r == 0) && (c == 0);
33 | if (isOrigin || getPath(grid, r - 1, c, path, failed) || getPath(grid, r, c - 1, path, failed)) {
34 | path.add(p);
35 | return true;
36 | } else {
37 | failed.add(p);
38 | return false;
39 | }
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/recursivedp/_08_03_MagicIndex.java:
--------------------------------------------------------------------------------
1 | package recursivedp;
2 |
3 | /**
4 | * Magic Index: A magic index in an array A[0...n-1] is defined to be an index such that A[i] = i.
5 | * Given a sorted array of distinct integers, write a method to find a magic index, if one exists, in array A.
6 | */
7 | class _08_03_MagicIndex {
8 |
9 | int findMagicIndex(int[] arr) {
10 | if (arr == null || arr.length == 0) {
11 | return -1;
12 | }
13 |
14 | int start = 0;
15 | int end = arr.length - 1;
16 | while (start <= end) {
17 | int mid = start + (end - start) / 2;
18 | if (arr[mid] == mid) {
19 | return mid;
20 | } else if (arr[mid] > mid) {
21 | end = mid - 1;
22 | } else {
23 | start = mid + 1;
24 | }
25 | }
26 | return -1;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/recursivedp/_08_04_PowerSet.java:
--------------------------------------------------------------------------------
1 | package recursivedp;
2 |
3 | import java.util.Collections;
4 | import java.util.HashSet;
5 | import java.util.Set;
6 | import java.util.stream.Collectors;
7 |
8 | /**
9 | * Write a method to return all subsets of a set
10 | */
11 | class _08_04_PowerSet {
12 |
13 | Set> subSets(Set set) {
14 | if (set.isEmpty()) return Collections.emptySet();
15 | Set> subsets = new HashSet<>();
16 | subsets.add(new HashSet<>());
17 | for (Integer integer : set) {
18 | subsets = grow(subsets, integer);
19 | }
20 | return subsets;
21 | }
22 |
23 | private Set> grow(Set> subsets, Integer i) {
24 | Set> grown = subsets.stream().map(set -> grow(i, set)).collect(Collectors.toSet());
25 | grown.addAll(subsets);
26 | return grown;
27 | }
28 |
29 | private HashSet grow(Integer i, Set set) {
30 | HashSet newSet = new HashSet<>(set);
31 | newSet.add(i);
32 | return newSet;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/recursivedp/_08_05_RecursiveMultiply.java:
--------------------------------------------------------------------------------
1 | package recursivedp;
2 |
3 | /**
4 | * Write a recursive function to multiply two positive integers without using the * operator.
5 | * You can use addition, subtraction, and bit shifting, but you should minimize the number of those operations.
6 | */
7 | class _08_05_RecursiveMultiply {
8 |
9 | int multiple(int a, int b) {
10 | int small = Math.min(a, b);
11 | int big = Math.max(a, b);
12 | return multipleRecursive(big, small);
13 | }
14 |
15 | private int multipleRecursive(int big, int small) {
16 | if (small == 0) return 0;
17 | if (small == 1) return big;
18 | int half = multipleRecursive(big, small >> 1);
19 | if (small % 2 == 0) return half + half;
20 | else return half + half + big;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/recursivedp/_08_06_HanoiTowers.java:
--------------------------------------------------------------------------------
1 | package recursivedp;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * In the classic problem of the towers of Hanoi,
8 | * you have 3 towers and N disks of different sizes which can slide onto any tower.
9 | * The puzzle starts with disks sorted in ascending order of size from top to bottom
10 | * (i.e., each disk sits on top of an even larger one).
11 | * You have the following constraints:
12 | * (1) Only one disk can be moved at a time.
13 | * (2) A disk is slid off the top of one tower onto another tower.
14 | * (3) A disk cannot be placed on top of a smaller disk.
15 | * Write a program to move the disks from the first tower to the last using stacks.
16 | */
17 | class _08_06_HanoiTowers {
18 |
19 | private static final int LEFT = 1; // id(left) = 1
20 | private static final int RIGHT = 3; // id(right) = 3
21 | private static final int SUM = 6; // id(center) = 2
22 |
23 | List leftToRight(int n) {
24 | return move(n, LEFT, RIGHT);
25 | }
26 |
27 | private List move(int n, int from, int to) {
28 | if (n == 1) {
29 | List moves = new ArrayList<>();
30 | moves.add(from);
31 | moves.add(to);
32 | return moves;
33 | }
34 | int buffer = SUM - from - to;
35 | List moves = move(n - 1, from, buffer);
36 | moves.add(from);
37 | moves.add(to);
38 | moves.addAll(move(n - 1, buffer, to));
39 | return moves;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/recursivedp/_08_07_PermutationWithoutDup.java:
--------------------------------------------------------------------------------
1 | package recursivedp;
2 |
3 | import java.util.Collections;
4 | import java.util.HashSet;
5 | import java.util.Set;
6 |
7 | /**
8 | * Write a method to compute all permutations of a string of unique characters.
9 | */
10 | class _08_07_PermutationWithoutDup {
11 |
12 | Set computePermutation(String str) {
13 | if (str.length() == 0) return Collections.singleton("");
14 | Set result = new HashSet<>();
15 | for (int i = 0; i < str.length(); i++) {
16 | char c = str.charAt(i);
17 | String prefix = str.substring(0, i);
18 | String remainder = str.substring(i + 1, str.length());
19 | Set partial = computePermutation(prefix + remainder);
20 | for (String s : partial) {
21 | result.add(c + s);
22 | }
23 | }
24 | return result;
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/recursivedp/_08_08_PermutationWithDup.java:
--------------------------------------------------------------------------------
1 | package recursivedp;
2 |
3 | import java.util.*;
4 |
5 | /**
6 | * Write a method to compute all permutations of a string whose characters
7 | * are not necessarily unique. The list of permutations should not have duplicates.
8 | */
9 | class _08_08_PermutationWithDup {
10 |
11 | Set computePermutation(String str) {
12 | if (str.length() == 0) return Collections.singleton("");
13 | Map frequencyTable = buildFrequencyTable(str);
14 | Set result = new HashSet<>();
15 | dfs(frequencyTable, "", str.length(), result);
16 | return result;
17 | }
18 |
19 | private void dfs(Map map, String prefix, int remaining, Set result) {
20 | if (remaining == 0) {
21 | result.add(prefix);
22 | } else {
23 | for (Character c : map.keySet()) {
24 | int count = map.get(c);
25 | if (count > 0) {
26 | map.put(c, count - 1);
27 | dfs(map, prefix + c, remaining - 1, result);
28 | map.put(c, count);
29 | }
30 | }
31 | }
32 | }
33 |
34 | private Map buildFrequencyTable(String str) {
35 | Map m = new HashMap<>();
36 | for (int i = 0; i < str.length(); i++) {
37 | m.compute(str.charAt(i), (k, v) -> v == null ? 1 : v + 1);
38 | }
39 | return m;
40 | }
41 |
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/recursivedp/_08_09_Parens.java:
--------------------------------------------------------------------------------
1 | package recursivedp;
2 |
3 | import java.util.Collections;
4 | import java.util.HashSet;
5 | import java.util.Set;
6 |
7 | /**
8 | * Implement an algorithm to print all valid (e.g., properly opened and closed) combinations of n pairs of parentheses.
9 | * EXAMPLE
10 | * Input: 3
11 | * Output: ((())), (()()), (())(), ()(()), ()()()
12 | */
13 | public class _08_09_Parens {
14 |
15 | //time o(2^n) space o(n) where n = pairs * 2
16 | Set combine(int pairs) {
17 | if (pairs == 0) return Collections.emptySet();
18 | Set result = new HashSet<>();
19 | char[] buff = new char[pairs * 2];
20 | doCombine(pairs, 0, 0, result, buff);
21 | return result;
22 | }
23 |
24 | private void doCombine(int pairs, int open, int close, Set result, char[] buff) {
25 | if (open == pairs && close == pairs) {
26 | result.add(String.valueOf(buff));
27 | } else {
28 | if (open < pairs) {
29 | buff[open + close] = '(';
30 | doCombine(pairs, open + 1, close, result, buff);
31 | }
32 | if (close < open) {
33 | buff[open + close] = ')';
34 | doCombine(pairs, open, close + 1, result, buff);
35 | }
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/recursivedp/_08_10_PaintFill.java:
--------------------------------------------------------------------------------
1 | package recursivedp;
2 |
3 | /**
4 | * Paint Fill: Implement the "paint fill" function that one might see on many image editing programs.
5 | * That is, given a screen (represented by a two-dimensional array of colors), a point, and a new color,
6 | * fill in the surrounding area until the color changes from the original color.
7 | *
8 | * EXAMPLE
9 | *
10 | * [0, 1, 1]
11 | * [1, 1, 0]
12 | * [1, 0, 0]
13 | *
14 | * Given a new point at (2, 2) and new color 2, the expected screen after paint filling should be
15 | * [0, 1, 1]
16 | * [1, 1, 2]
17 | * [1, 2, 2]
18 | */
19 | public class _08_10_PaintFill {
20 |
21 | private int[][] screen;
22 | private int rows;
23 | private int cols;
24 | private int oldColor;
25 | private int newColor;
26 |
27 | int[][] paintFill(int[][] screen, int row, int col, int newColor) {
28 | this.screen = screen;
29 | rows = screen.length;
30 | if (rows == 0) throw new IllegalArgumentException("scree must contain at least one row");
31 | cols = screen[0].length;
32 | oldColor = screen[row][col];
33 | this.newColor = newColor;
34 | doPaint(row, col);
35 | return screen;
36 | }
37 |
38 | private void doPaint(int row, int col) {
39 | if (screen[row][col] != oldColor) return;
40 |
41 | screen[row][col] = newColor;
42 | if (row > 0) {
43 | doPaint(row - 1, col);
44 | }
45 |
46 | if (row < rows - 1) {
47 | doPaint(row + 1, col);
48 | }
49 |
50 | if (col > 0) {
51 | doPaint(row, col - 1);
52 | }
53 |
54 | if (col < cols - 1) {
55 | doPaint(row, col + 1);
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/main/java/recursivedp/_08_11_Coins.java:
--------------------------------------------------------------------------------
1 | package recursivedp;
2 |
3 | /**
4 | * Coins: Given an infinite number of quarters (25 cents), dimes (10 cents), nickels (5 cents), and pennies (1 cent),
5 | * write code to calculate the number of ways of representing n cents.
6 | */
7 | public class _08_11_Coins {
8 |
9 | int makeChangeWithQuarterDimeNickelPenny(int n) {
10 | int[] components = {25, 10, 5, 1};
11 | int[][] cache = new int[n + 1][components.length];
12 | return makeChange(n, 0, components, cache);
13 | }
14 |
15 | private int makeChange(int amount, int index, int[] components, int[][] cache) {
16 | if (amount == 0 || index == components.length - 1) {
17 | return 1;
18 | }
19 | if (cache[amount][index] > 0) {
20 | return cache[amount][index];
21 | }
22 | int ways = 0;
23 | for (int remaining = amount; remaining >= 0; remaining -= components[index]) {
24 | ways += makeChange(remaining, index + 1, components, cache);
25 | }
26 | cache[amount][index] = ways;
27 | return ways;
28 | }
29 |
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/recursivedp/_08_12_EightQueens.java:
--------------------------------------------------------------------------------
1 | package recursivedp;
2 |
3 | import java.awt.*;
4 | import java.util.ArrayList;
5 | import java.util.Arrays;
6 | import java.util.List;
7 |
8 | /**
9 | * Write an algorithm to print all ways of arranging eight queens on an 8x8 chess board
10 | * so that none of them share the same row, column, or diagonal.
11 | * In this case, "diagonal" means all diagonals, not just the two that bisect the board.
12 | */
13 | public class _08_12_EightQueens {
14 |
15 | private static final int SIZE = 8;
16 |
17 | List> arrange() {
18 | List> result = new ArrayList<>();
19 | Constraints constraints = new Constraints();
20 | dfs(0, new Point[SIZE], constraints, result);
21 | return result;
22 | }
23 |
24 | private void dfs(int row, Point[] points, Constraints constraints, List> result) {
25 | if (row == SIZE) {
26 | result.add(Arrays.asList(points));
27 | return;
28 | }
29 |
30 | for (int col = 0; col < SIZE; col++) {
31 | Point p = new Point(row, col);
32 | if (constraints.isFeasible(p)) {
33 | constraints.mark(p);
34 | points[row] = p;
35 | dfs(row + 1, points, constraints, result);
36 | constraints.unmark(p);
37 | }
38 | }
39 |
40 | }
41 |
42 | private static class Constraints {
43 | private boolean[] rows = new boolean[SIZE];
44 | private boolean[] cols = new boolean[SIZE];
45 | private boolean[] positive = new boolean[SIZE * 2 - 1];
46 | private boolean[] negative = new boolean[SIZE * 2 - 1];
47 |
48 | private void mark(Point p) {
49 | rows[p.x] = true;
50 | cols[p.y] = true;
51 | positive[toPositiveDiagonal(p)] = true;
52 | negative[toNegativeDiagonal(p)] = true;
53 | }
54 |
55 | private void unmark(Point p) {
56 | rows[p.x] = false;
57 | cols[p.y] = false;
58 | positive[toPositiveDiagonal(p)] = false;
59 | negative[toNegativeDiagonal(p)] = false;
60 | }
61 |
62 | private boolean isFeasible(Point p) {
63 | return !rows[p.x]
64 | && !cols[p.y]
65 | && !positive[toPositiveDiagonal(p)]
66 | && !negative[toNegativeDiagonal(p)];
67 | }
68 |
69 | private int toPositiveDiagonal(Point p) {
70 | return p.x + p.y;
71 | }
72 |
73 |
74 | private int toNegativeDiagonal(Point p) {
75 | return SIZE - 1 - (p.x - p.y);
76 | }
77 |
78 | }
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/src/main/java/recursivedp/_08_13_StackOfBoxes.java:
--------------------------------------------------------------------------------
1 | package recursivedp;
2 |
3 | import java.util.Comparator;
4 | import java.util.List;
5 |
6 | /**
7 | * You have a stack of n boxes, with widths wi, heights hi, and depths di.
8 | * The boxes cannot be rotated and can only be stacked on top of one another
9 | * if each box in the stack is strictly larger than the box above it
10 | * in width, height, and depth.
11 | *
12 | * Implement a method to compute the height of the tallest possible stack.
13 | * The height of a stack is the sum of the heights of each box.
14 | */
15 | public class _08_13_StackOfBoxes {
16 |
17 | int createStack(List boxes) {
18 | boxes.sort(Comparator.comparing(b -> -b.h));
19 | int[] cache = new int[boxes.size()];
20 | int max = 0;
21 | for (int i = 0; i < boxes.size(); i++) {
22 | int h = doCreateStack(boxes, i, cache);
23 | max = Math.max(max, h);
24 | }
25 | return max;
26 | }
27 |
28 | private int doCreateStack(List boxes, int bottom, int[] cache) {
29 | if (cache[bottom] > 0) return cache[bottom];
30 | if (bottom == boxes.size()) return 0;
31 | int max = 0;
32 | Box current = boxes.get(bottom);
33 | for (int i = bottom + 1; i < boxes.size(); i++) {
34 | Box next = boxes.get(i);
35 | if (next.canPutAbove(current)) {
36 | int h = doCreateStack(boxes, i, cache);
37 | max = Math.max(max, h);
38 | }
39 | }
40 | int total = current.h + max;
41 | cache[bottom] = total;
42 | return total;
43 | }
44 |
45 | static class Box {
46 | int w;
47 | int h;
48 | int d;
49 |
50 | Box(int w, int h, int d) {
51 | this.w = w;
52 | this.h = h;
53 | this.d = d;
54 | }
55 |
56 | boolean canPutAbove(Box that) {
57 | return that.h > h && that.w > w && that.d > d;
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/recursivedp/_08_14_BooleanEvaluation.java:
--------------------------------------------------------------------------------
1 | package recursivedp;
2 |
3 | /**
4 | * Given a boolean expression consisting of the symbols 0 (false), 1 (true), & (AND), | (OR), and ^ (XOR),
5 | * and a desired boolean result value result, implement a function to count the number of ways of
6 | * parenthesizing the expression such that it evaluates to result.
7 | *
8 | * EXAMPLE
9 | * countEval("1^0|0|1", false) -> 2
10 | * countEval("0&0&0&1^1|0", true) -> 10
11 | */
12 | public class _08_14_BooleanEvaluation {
13 |
14 | int evaluate(String expression, boolean result) {
15 | if (expression.isEmpty()) return 0;
16 | Pair[][] cache = new Pair[expression.length() + 1][expression.length() + 1];
17 | Pair pair = doEvaluate(expression, 0, expression.length(), cache);
18 | return result ? pair.trueCount : pair.falseCount;
19 | }
20 |
21 | private Pair doEvaluate(String exp, int start, int end, Pair[][] cache) {
22 | if (cache[start][end] != null) {
23 | return cache[start][end];
24 | }
25 | Pair result;
26 | if (end - start == 1) {
27 | result = countPair(exp.charAt(start) == '1');
28 | } else {
29 | int ops = (end - start - 1) / 2;
30 | result = new Pair(0, 0);
31 | for (int i = 0; i < ops; i++) {
32 | int j = start + (i * 2) + 1;
33 | Pair leftPair = doEvaluate(exp, start, j, cache);
34 | Pair rightPair = doEvaluate(exp, j + 1, end, cache);
35 | char operator = exp.charAt(j);
36 | Pair combined = combine(leftPair, rightPair, operator);
37 | result = plus(result, combined);
38 | }
39 | }
40 | cache[start][end] = result;
41 | return result;
42 | }
43 |
44 | private Pair plus(Pair p1, Pair p2) {
45 | return new Pair(p1.trueCount + p2.trueCount, p1.falseCount + p2.falseCount);
46 | }
47 |
48 | private Pair combine(Pair left, Pair right, char operator) {
49 | int tt = left.trueCount * right.trueCount;
50 | int tf = left.trueCount * right.falseCount;
51 | int ft = left.falseCount * right.trueCount;
52 | int ff = left.falseCount * right.falseCount;
53 | switch (operator) {
54 | case '&':
55 | return new Pair(tt, tf + ft + ff);
56 | case '|':
57 | return new Pair(tt + tf + ft, ff);
58 | case '^':
59 | return new Pair(tf + ft, tt + ff);
60 | default:
61 | throw new UnsupportedOperationException();
62 | }
63 | }
64 |
65 | private Pair countPair(boolean result) {
66 | return result ? new Pair(1, 0) : new Pair(0, 1);
67 | }
68 |
69 |
70 | static class Pair {
71 | int trueCount;
72 | int falseCount;
73 |
74 | Pair(int trueCount, int falseCount) {
75 | this.trueCount = trueCount;
76 | this.falseCount = falseCount;
77 | }
78 | }
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/src/main/java/sortingsearching/_10_01_SortedMerge.java:
--------------------------------------------------------------------------------
1 | package sortingsearching;
2 |
3 | /**
4 | * You are given two sorted arrays, A and B, where A has a large enough buffer at the end to hold B.
5 | * Write a method to merge B into A in sorted order.
6 | */
7 | public class _10_01_SortedMerge {
8 |
9 | int[] merge(int[] big, int[] small) {
10 | int b = big.length - small.length - 1;
11 | int s = small.length - 1;
12 | int i = big.length - 1;
13 | while (b >= 0 || s >= 0) {
14 | if (b < 0) {
15 | big[i--] = small[s--];
16 | } else if (s < 0) {
17 | break;
18 | } else {
19 | if (small[s] > big[b]) {
20 | big[i--] = small[s--];
21 | } else {
22 | big[i--] = big[b--];
23 | }
24 | }
25 | }
26 | return big;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/sortingsearching/_10_02_GroupAnagrams.java:
--------------------------------------------------------------------------------
1 | package sortingsearching;
2 |
3 | import java.util.*;
4 | import java.util.stream.Collectors;
5 |
6 | /**
7 | * Write a method to sort an array of strings so that all the anagrams are next to each other.
8 | */
9 | public class _10_02_GroupAnagrams {
10 |
11 | /**
12 | * time o(n) ( o(nklogk) when k is the max length of a word, klogk becomes constant so we have o(n))
13 | * space o(n)
14 | */
15 | List groupAnagrams(List words) {
16 | if (words == null || words.isEmpty()) return words;
17 | Map> anagrams = new HashMap<>();
18 | for (String word : words) {
19 | anagrams.computeIfAbsent(sorted(word), k -> new ArrayList<>()).add(word);
20 | }
21 | return anagrams.values().stream().flatMap(List::stream).collect(Collectors.toList());
22 | }
23 |
24 | private String sorted(String word) {
25 | char[] chars = word.toCharArray();
26 | Arrays.sort(chars);
27 | return String.valueOf(chars);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/sortingsearching/_10_03_SearchInRotatedArray.java:
--------------------------------------------------------------------------------
1 | package sortingsearching;
2 |
3 | import java.util.Arrays;
4 |
5 | /**
6 | * Given a sorted array of n integers that has been rotated an unknown number of times,
7 | * write code to find an element in the array. You may assume that the array was originally sorted in increasing order.
8 | * EXAMPLE
9 | * input:find 5 in {15, 16, 19, 20, 25, 1, 3, 4, 5, 7, 10, 14}
10 | * output: 8 (index of 5 in the array)
11 | */
12 | public class _10_03_SearchInRotatedArray {
13 |
14 | int find(int[] arr, int target) {
15 | if (arr == null || arr.length == 0) return -1;
16 | int start = 0;
17 | int end = arr.length - 1;
18 | while (start <= end) {
19 | if (arr[start] <= arr[end]) {
20 | return binarySearch(arr, start, end, target);
21 | } else {
22 | int middle = start + (end - start) / 2;
23 | if (arr[middle] >= arr[start]) {
24 | if (target >= arr[start] && target <= arr[middle]) {
25 | return binarySearch(arr, start, middle, target);
26 | } else {
27 | start = middle + 1;
28 | }
29 | } else {
30 | if (target >= arr[middle] && target <= arr[end]) {
31 | return binarySearch(arr, middle, end, target);
32 | } else {
33 | end = middle - 1;
34 | }
35 | }
36 | }
37 | }
38 | return -1;
39 | }
40 |
41 | private int binarySearch(int[] arr, int start, int end, int target) {
42 | return Math.max(-1, Arrays.binarySearch(arr, start, end + 1, target));
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/sortingsearching/_10_04_SortedSearch.java:
--------------------------------------------------------------------------------
1 | package sortingsearching;
2 |
3 | import java.util.Arrays;
4 |
5 | /**
6 | * You are given an array like data structure Listy which lacks a size method.
7 | * It does, however, have an elementAt(i) method that returns the element at index i in o(1) time.
8 | * If i is beyond the bounds of the data structure, it returns -1.
9 | * (For this reason, the data structure only supports positive integers.)
10 | * Given a Listy which contains sorted, positive integers, find the index at which an element x occurs.
11 | * If x occurs multiple times, you may return any index.
12 | */
13 | public class _10_04_SortedSearch {
14 |
15 | int sortedSearch(Listy listy, int target) {
16 | if (target <= 0) return -1;
17 | return doSearch(listy, 0, 0, target);
18 | }
19 |
20 | private int doSearch(Listy listy, int start, int end, int target) {
21 | if (end < start) return -1;
22 | if (listy.at(start) == -1) return -1;
23 | if (target <= listy.at(end)) {
24 | int mid = start + (end - start) / 2;
25 | if (target == listy.at(mid)) {
26 | return mid;
27 | } else if (target < listy.at(mid)) {
28 | return doSearch(listy, start, mid - 1, target);
29 | } else {
30 | return doSearch(listy, mid + 1, end, target);
31 | }
32 | } else if (listy.at(end) == -1) {
33 | return doSearch(listy, start, start + (end - start) / 2, target);
34 | } else {
35 | return doSearch(listy, end + 1, (end + 1) * 2, target);
36 | }
37 | }
38 |
39 | static class Listy {
40 | private int[] elems;
41 |
42 | static Listy of(int... elems) {
43 | if (elems == null || Arrays.stream(elems).anyMatch(v -> v <= 0)) {
44 | throw new IllegalArgumentException("elems should contain only positive integers");
45 | }
46 | Listy listy = new Listy();
47 | listy.elems = elems;
48 | return listy;
49 | }
50 |
51 | int at(int i) {
52 | if (i < elems.length && i >= 0) {
53 | return elems[i];
54 | }
55 | return -1;
56 | }
57 |
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/sortingsearching/_10_05_SparseSearch.java:
--------------------------------------------------------------------------------
1 | package sortingsearching;
2 |
3 | import java.util.Objects;
4 |
5 | /**
6 | * Given a sorted array of strings that is interspersed with empty strings,
7 | * write a method to find the location of a given string.
8 | */
9 | public class _10_05_SparseSearch {
10 |
11 | int find(String[] arr, String target) {
12 | if (target == null || Objects.equals("", target)) return -1;
13 | return doFind(arr, target, 0, arr.length - 1);
14 | }
15 |
16 | private int doFind(String[] arr, String target, int start, int end) {
17 | if (start > end) return -1;
18 | int mid = start + (end - start) / 2;
19 |
20 |
21 | if (arr[mid].isEmpty()) {
22 | int left = mid;
23 | int right = mid;
24 | while (true) {
25 | if (left < start && right > end) return -1;
26 | if (left >= start && !arr[left].isEmpty()) {
27 | mid = left;
28 | break;
29 | }
30 |
31 | if (right <= end && !arr[right].isEmpty()) {
32 | mid = right;
33 | break;
34 | }
35 | left--;
36 | right++;
37 | }
38 | }
39 |
40 | if (arr[mid].equals(target)) {
41 | return mid;
42 | } else if (target.compareTo(arr[mid]) < 0) {
43 | return doFind(arr, target, start, mid - 1);
44 | } else {
45 | return doFind(arr, target, mid + 1, end);
46 | }
47 | }
48 |
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/stackqueue/_03_01_ThreeInOne.java:
--------------------------------------------------------------------------------
1 | package stackqueue;
2 |
3 | import java.util.NoSuchElementException;
4 |
5 | /**
6 | * Describe how you could use a single array to implement three stacks
7 | */
8 | class _03_01_ThreeInOne {
9 |
10 | private final int[] arr;
11 | private StackInfo[] stacks;
12 |
13 |
14 | _03_01_ThreeInOne(int initSize) {
15 | arr = new int[3 * initSize];
16 | stacks = new StackInfo[3];
17 | for (int i = 0; i < stacks.length; i++) {
18 | stacks[i] = new StackInfo(i * initSize, initSize);
19 | }
20 | }
21 |
22 | void push(int stackNum, int val) {
23 | checkStackNum(stackNum);
24 | StackInfo stackInfo = stacks[stackNum];
25 | if (stackInfo.isFull()) {
26 | if (isAllFull()) throw new IllegalStateException("array is full");
27 | expand(stackNum);
28 | }
29 | arr[adjust(stackInfo.peek() + 1)] = val;
30 | stackInfo.size++;
31 | }
32 |
33 | private boolean isAllFull() {
34 | int sum = 0;
35 | for (StackInfo stack : stacks) {
36 | sum += stack.size;
37 | }
38 | return sum >= arr.length;
39 | }
40 |
41 | private void expand(int stackNum) {
42 | shift(nextStack(stackNum));
43 | stacks[stackNum].capacity++;
44 | }
45 |
46 | private int adjust(int i) {
47 | return ((i % arr.length) + arr.length) % arr.length;
48 | }
49 |
50 | private void shift(int stackNumb) {
51 | StackInfo stackInfo = stacks[stackNumb];
52 | if (stackInfo.isFull()) {
53 | shift(nextStack(stackNumb));
54 | }
55 | int cur = adjust(stackInfo.peek() + 1);
56 | while (cur != stackInfo.start) {
57 | int previous = adjust(cur - 1);
58 | arr[cur] = arr[previous];
59 | cur = previous;
60 | }
61 | stackInfo.start = adjust(stackInfo.start + 1);
62 | }
63 |
64 | private int nextStack(int stackNumb) {
65 | return (stackNumb + 1) % stacks.length;
66 | }
67 |
68 | private void checkStackNum(int stackNum) {
69 | if (stackNum >= stacks.length || stackNum < 0)
70 | throw new IllegalArgumentException("Stack doesn't exist " + stackNum + " 0 - 2");
71 | }
72 |
73 | int pop(int stackNum) {
74 | checkStackNum(stackNum);
75 | StackInfo stackInfo = stacks[stackNum];
76 | if (stackInfo.isEmpty()) throw new NoSuchElementException("stack is empty");
77 | int peekIndex = stackInfo.peek() % arr.length;
78 | int peek = arr[peekIndex];
79 | arr[peekIndex] = 0;
80 | stackInfo.size--;
81 | return peek;
82 | }
83 |
84 | private static class StackInfo {
85 | int start;
86 | int size;
87 | int capacity;
88 |
89 | StackInfo(int start, int capacity) {
90 | this.start = start;
91 | this.capacity = capacity;
92 | }
93 |
94 | int peek() {
95 | return start + size - 1;
96 | }
97 |
98 | boolean isEmpty() {
99 | return size == 0;
100 | }
101 |
102 | boolean isFull() {
103 | return size == capacity;
104 | }
105 | }
106 |
107 |
108 | }
109 |
--------------------------------------------------------------------------------
/src/main/java/stackqueue/_03_02_MinStack.java:
--------------------------------------------------------------------------------
1 | package stackqueue;
2 |
3 | import java.util.Stack;
4 |
5 | /**
6 | * How would you design a stack which, in addition to push and pop, has a function min which returns the minimum element? Push, pop and min should all operate in 0(1) time.
7 | */
8 | class _03_02_MinStack {
9 |
10 | private Stack vals = new Stack<>();
11 | private Stack mins = new Stack<>();
12 |
13 | void push(int val) {
14 | vals.push(val);
15 | if (mins.isEmpty() || val < mins.peek()) {
16 | mins.push(val);
17 | }
18 | }
19 |
20 | int pop() {
21 | int val = vals.pop();
22 | if (val == mins.peek()) {
23 | mins.pop();
24 | }
25 | return val;
26 | }
27 |
28 | int min() {
29 | return mins.peek();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/stackqueue/_03_03_StackOfPlates.java:
--------------------------------------------------------------------------------
1 | package stackqueue;
2 |
3 | import java.util.*;
4 |
5 | class _03_03_StackOfPlates {
6 |
7 | private final int threshold;
8 | private final List> stacks;
9 |
10 | _03_03_StackOfPlates(int threshold) {
11 | this.threshold = threshold;
12 | stacks = new ArrayList<>();
13 | }
14 |
15 | void push(int val) {
16 | if (stacks.isEmpty() || isLastStackFull()) {
17 | stacks.add(new LinkedList<>());
18 | }
19 | lastStack().push(val);
20 | }
21 |
22 | private boolean isLastStackFull() {
23 | return lastStack().size() == threshold;
24 | }
25 |
26 | private Deque lastStack() {
27 | return stacks.get(stacks.size() - 1);
28 | }
29 |
30 | int pop() {
31 | if (stacks.isEmpty()) throw new EmptyStackException();
32 | Deque stack = lastStack();
33 | int val = stack.pop();
34 | if (stack.isEmpty()) removeLast();
35 | return val;
36 | }
37 |
38 | int popAt(int stackNum) {
39 | int val = stacks.get(stackNum).pop();
40 | for (int i = stackNum; i < stacks.size(); i++) {
41 | if (i + 1 < stacks.size()) {
42 | Deque nextStack = stacks.get(i + 1);
43 | stacks.get(i).push(nextStack.removeLast());
44 | }
45 | }
46 | if (lastStack().isEmpty()) {
47 | removeLast();
48 | }
49 | return val;
50 | }
51 |
52 | private void removeLast() {
53 | stacks.remove(stacks.size() - 1);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/main/java/stackqueue/_03_04_QueueViaStacks.java:
--------------------------------------------------------------------------------
1 | package stackqueue;
2 |
3 | import java.util.Stack;
4 |
5 | class _03_04_QueueViaStacks {
6 |
7 | private final Stack inbox = new Stack<>();
8 | private final Stack outbox = new Stack<>();
9 |
10 | void enqueue(int val) {
11 | inbox.add(val);
12 | }
13 |
14 | int size() {
15 | return inbox.size() + outbox.size();
16 | }
17 |
18 | int peek() {
19 | fillOutbox();
20 | return outbox.peek();
21 | }
22 |
23 | int dequeue() {
24 | fillOutbox();
25 | return outbox.pop();
26 | }
27 |
28 | private void fillOutbox() {
29 | if (outbox.isEmpty()) {
30 | while (!inbox.isEmpty()) {
31 | outbox.push(inbox.pop());
32 | }
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/stackqueue/_03_05_SortStack.java:
--------------------------------------------------------------------------------
1 | package stackqueue;
2 |
3 | import java.util.Stack;
4 |
5 | /**
6 | * Write a program to sort a stack such that the smallest items are on the top.
7 | * You can use an additional temporary stack,
8 | * but you may not copy the elements into any other data structure (such as an array).
9 | * The stack supports the following operations: push, pop, peek, and isEmpty.
10 | */
11 | class _03_05_SortStack {
12 |
13 | Stack sort(Stack stack) {
14 | Stack tmp = new Stack<>();
15 | while (!stack.isEmpty()) {
16 | int top = stack.pop();
17 | if (!tmp.isEmpty() && top > tmp.peek()) {
18 | while (!tmp.isEmpty()) {
19 | stack.push(tmp.pop());
20 | }
21 | }
22 | tmp.push(top);
23 | }
24 | return tmp;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/stackqueue/_03_06_AnimalShelter.java:
--------------------------------------------------------------------------------
1 | package stackqueue;
2 |
3 | import java.util.LinkedList;
4 |
5 | /**
6 | * An animal shelter, which holds only dogs and cats, operates on a strictly "first in, first out" basis.
7 | * People must adopt either the "oldest" (based on arrival time) of all animals at the shelter,
8 | * or they can select whether they would prefer a dog or a cat (and will receive the oldest animal of that type).
9 | * They cannot select which specific animal they would like.
10 | *
11 | * Create the data structures to maintain this system and implement operations such as
12 | * enqueue, dequeueAny, dequeueDog, and dequeueCat.
13 | *
14 | * You may use the built-in Linked list data structure.
15 | */
16 | class _03_06_AnimalShelter {
17 |
18 | private int counter = 0;
19 | private LinkedList dogs = new LinkedList<>();
20 | private LinkedList cats = new LinkedList<>();
21 |
22 | void enqueueDog(int num) {
23 | dogs.add(new Animal(num, counter++));
24 | }
25 |
26 | void enqueueCat(int num) {
27 | cats.add(new Animal(num, counter++));
28 | }
29 |
30 | int dequeueAny() {
31 | if (dogs.isEmpty()) {
32 | return cats.remove().num;
33 | } else if (cats.isEmpty()) {
34 | return dogs.remove().num;
35 | } else {
36 | if (dogs.peek().counter < cats.peek().counter) {
37 | return dogs.remove().num;
38 | } else {
39 | return cats.remove().num;
40 | }
41 | }
42 | }
43 |
44 | int dequeueDog() {
45 | return dogs.remove().num;
46 | }
47 |
48 | int dequeueCat() {
49 | return cats.remove().num;
50 | }
51 |
52 | static class Animal {
53 | int num;
54 | int counter;
55 |
56 | Animal(int num, int counter) {
57 | this.num = num;
58 | this.counter = counter;
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/main/java/treegraph/BinaryTreeNode.java:
--------------------------------------------------------------------------------
1 | package treegraph;
2 |
3 | class BinaryTreeNode {
4 | int val;
5 | BinaryTreeNode left;
6 | BinaryTreeNode right;
7 |
8 | BinaryTreeNode(int val) {
9 | this.val = val;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/java/treegraph/Digraph.java:
--------------------------------------------------------------------------------
1 | package treegraph;
2 |
3 | import java.util.ArrayList;
4 | import java.util.LinkedList;
5 | import java.util.List;
6 |
7 | class Digraph {
8 |
9 | private final List> adjacent;
10 |
11 | Digraph(int vertexCount) {
12 | adjacent = new ArrayList<>(vertexCount);
13 | for (int i = 0; i < vertexCount; i++) {
14 | adjacent.add(new LinkedList<>());
15 | }
16 | }
17 |
18 | void addEdge(int from, int to) {
19 | adjacent.get(from).add(to);
20 | }
21 |
22 | Iterable adjacent(int v) {
23 | return adjacent.get(v);
24 | }
25 |
26 | int size() {
27 | return adjacent.size();
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/treegraph/ParentAwareBinaryTreeNode.java:
--------------------------------------------------------------------------------
1 | package treegraph;
2 |
3 | class ParentAwareBinaryTreeNode {
4 | ParentAwareBinaryTreeNode parent;
5 | ParentAwareBinaryTreeNode left;
6 | ParentAwareBinaryTreeNode right;
7 | int val;
8 |
9 | ParentAwareBinaryTreeNode(int val) {
10 | this.val = val;
11 | }
12 |
13 | ParentAwareBinaryTreeNode addLeft(int val) {
14 | ParentAwareBinaryTreeNode left = new ParentAwareBinaryTreeNode(val);
15 | this.left = left;
16 | left.parent = this;
17 | return left;
18 | }
19 |
20 | ParentAwareBinaryTreeNode addRight(int val) {
21 | ParentAwareBinaryTreeNode right = new ParentAwareBinaryTreeNode(val);
22 | this.right = right;
23 | right.parent = this;
24 | return right;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/treegraph/_04_01_RouteBetweenNodes.java:
--------------------------------------------------------------------------------
1 | package treegraph;
2 |
3 | /**
4 | * Given a directed graph, design an algorithm to find out whether
5 | * there is a route between two nodes.
6 | */
7 | class _04_01_RouteBetweenNodes {
8 |
9 | private final Digraph digraph;
10 | private boolean[] visited;
11 |
12 | _04_01_RouteBetweenNodes(Digraph digraph) {
13 | this.digraph = digraph;
14 | }
15 |
16 | boolean hasRoute(int source, int target) {
17 | visited = new boolean[digraph.size()];
18 | dfs(source);
19 | return visited[target];
20 | }
21 |
22 | private void dfs(int node) {
23 | visited[node] = true;
24 | for (int n : digraph.adjacent(node)) {
25 | if (!visited[n]) {
26 | dfs(n);
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/treegraph/_04_02_MinimalTree.java:
--------------------------------------------------------------------------------
1 | package treegraph;
2 |
3 | /**
4 | * Given a sorted (increasing order) array with unique integer elements, write an algorithm
5 | * to create a binary search tree with minimal height.
6 | */
7 | class _04_02_MinimalTree {
8 |
9 | // time o(N), space o(logN)
10 | BinaryTreeNode buildMinimalTree(int[] vals) {
11 | return build(vals, 0, vals.length - 1);
12 | }
13 |
14 | private BinaryTreeNode build(int[] vals, int start, int end) {
15 | if (start == end) {
16 | return new BinaryTreeNode(vals[start]);
17 | } else if (start > end) {
18 | return null;
19 | } else {
20 | int mid = start + (end - start) / 2;
21 | BinaryTreeNode binaryTreeNode = new BinaryTreeNode(vals[mid]);
22 | binaryTreeNode.left = build(vals, start, mid - 1);
23 | binaryTreeNode.right = build(vals, mid + 1, end);
24 | return binaryTreeNode;
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/treegraph/_04_03_ListOfDepths.java:
--------------------------------------------------------------------------------
1 | package treegraph;
2 |
3 | import java.util.ArrayList;
4 | import java.util.LinkedList;
5 | import java.util.List;
6 |
7 | class _04_03_ListOfDepths {
8 |
9 | //time o(N) space o(N)
10 | List> create(BinaryTreeNode node) {
11 | List> result = new ArrayList<>();
12 | dfs(result, node, 0);
13 | return result;
14 | }
15 |
16 | private void dfs(List> result, BinaryTreeNode node, int depth) {
17 | if (node == null) return;
18 | if (result.size() == depth) {
19 | result.add(new LinkedList<>());
20 | }
21 | result.get(depth).add(node.val);
22 | dfs(result, node.left, depth + 1);
23 | dfs(result, node.right, depth + 1);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/treegraph/_04_04_CheckBalanced.java:
--------------------------------------------------------------------------------
1 | package treegraph;
2 |
3 | /**
4 | * Implement a function to check if a binary tree is balanced.
5 | * For the purposes of this question, a balanced tree is defined to be a tree such that
6 | * the heights of the two subtrees of any node never differ by more than one.
7 | */
8 | class _04_04_CheckBalanced {
9 |
10 | //time o(N) space o(logN)
11 | boolean isBalanced(BinaryTreeNode root) {
12 | return isBalancedWithHeight(root) != -1;
13 | }
14 |
15 | private int isBalancedWithHeight(BinaryTreeNode root) {
16 | if (root == null) return 0;
17 | int hl = isBalancedWithHeight(root.left);
18 | int hr = isBalancedWithHeight(root.right);
19 | if (Math.abs(hl - hr) > 1 || hr == -1 || hl == -1) return -1;
20 | return Math.max(hl, hr) + 1;
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/treegraph/_04_05_ValidateBST.java:
--------------------------------------------------------------------------------
1 | package treegraph;
2 |
3 | /**
4 | * Implement a function to check if a binary tree is a binary search tree.
5 | */
6 | class _04_05_ValidateBST {
7 |
8 | private int pre = Integer.MIN_VALUE;
9 |
10 | boolean isBST(BinaryTreeNode root) {
11 | return inOrder(root);
12 | }
13 |
14 | private boolean inOrder(BinaryTreeNode node) {
15 | if (node == null) return true;
16 |
17 | if (!inOrder(node.left)) return false;
18 | if (node.val < pre) return false;
19 | pre = node.val;
20 | return inOrder(node.right);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/treegraph/_04_06_Successor.java:
--------------------------------------------------------------------------------
1 | package treegraph;
2 |
3 | /**
4 | * Write an algorithm to find the "next" node (i.e., in-order successor) of a given node in a binary search tree.
5 | * You may assume that each node has a link to its parent.
6 | */
7 | class _04_06_Successor {
8 | ParentAwareBinaryTreeNode findInOrderSuccessor(ParentAwareBinaryTreeNode node) {
9 | if (node == null) return null;
10 | if (node.right != null) {
11 | return leftMost(node.right);
12 | }
13 | ParentAwareBinaryTreeNode p = node.parent;
14 | while (p != null && p.parent != null) {
15 | if (p.parent.left == p) {
16 | return p.parent;
17 | } else {
18 | p = p.parent;
19 | }
20 | }
21 | return p;
22 | }
23 |
24 | private ParentAwareBinaryTreeNode leftMost(ParentAwareBinaryTreeNode node) {
25 | if (node == null) return null;
26 | while (node.left != null) {
27 | node = node.left;
28 | }
29 | return node;
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/treegraph/_04_07_BuildOrder.java:
--------------------------------------------------------------------------------
1 | package treegraph;
2 |
3 | import java.util.LinkedList;
4 | import java.util.List;
5 |
6 | /**
7 | * You are given a list of projects and a list of dependencies
8 | * (which is a list of pairs of projects, where the second project is dependent on the first project).
9 | * All of a project's dependencies must be built before the project is.
10 | * Find a build order that will allow the projects to be built.
11 | * If there is no valid build order, return an error.
12 | */
13 | class _04_07_BuildOrder {
14 |
15 | private boolean onStack[];
16 | private boolean visited[];
17 | private Digraph digraph;
18 | private LinkedList topological = new LinkedList<>();
19 |
20 | List findBuildOrder(Digraph digraph) {
21 | this.digraph = digraph;
22 | onStack = new boolean[digraph.size()];
23 | visited = new boolean[digraph.size()];
24 | for (int i = 0; i < digraph.size(); i++) {
25 | if (!visited[i]) {
26 | dfs(i);
27 | }
28 | }
29 | if (topological.size() != digraph.size()) return null;
30 | return topological;
31 | }
32 |
33 | private void dfs(int v) {
34 | onStack[v] = true;
35 | visited[v] = true;
36 | for (Integer adj : digraph.adjacent(v)) {
37 | if (visited[adj] && onStack[adj]) {
38 | return;
39 | }
40 | if (!visited[adj]) {
41 | dfs(adj);
42 | }
43 | }
44 | onStack[v] = false;
45 | topological.add(v);
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/treegraph/_04_08_FindCommonAncestor.java:
--------------------------------------------------------------------------------
1 | package treegraph;
2 |
3 | /**
4 | * Design an algorithm and write code to find the first common ancestor of two nodes in a binary tree.
5 | * Avoid storing additional nodes in a data structure. NOTE: This is not necessarily a binary search tree.
6 | */
7 | class _04_08_FindCommonAncestor {
8 |
9 | ParentAwareBinaryTreeNode findCommonAncestor(ParentAwareBinaryTreeNode a, ParentAwareBinaryTreeNode b) {
10 | int da = depthOf(a);
11 | int db = depthOf(b);
12 | ParentAwareBinaryTreeNode deeper = da > db ? a : b;
13 | ParentAwareBinaryTreeNode other = da > db ? b : a;
14 | ParentAwareBinaryTreeNode c = goUp(deeper, Math.abs(da - db));
15 | while (other != null && c != null) {
16 | if (other == c) return other;
17 | other = other.parent;
18 | c = c.parent;
19 | }
20 | return null;
21 | }
22 |
23 | private ParentAwareBinaryTreeNode goUp(ParentAwareBinaryTreeNode deeper, int delta) {
24 | while (delta > 0 && deeper != null) {
25 | deeper = deeper.parent;
26 | delta--;
27 | }
28 | return deeper;
29 | }
30 |
31 | private int depthOf(ParentAwareBinaryTreeNode node) {
32 | int depth = 0;
33 | while (node != null) {
34 | depth++;
35 | node = node.parent;
36 | }
37 | return depth;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/treegraph/_04_09_BSTSequences.java:
--------------------------------------------------------------------------------
1 | package treegraph;
2 |
3 | import java.util.ArrayList;
4 | import java.util.LinkedList;
5 | import java.util.List;
6 |
7 | /**
8 | * A binary search tree was created by traversing through an array from left to right and inserting each element.
9 | * Given a binary search tree with distinct elements, print all possible arrays that could have led to this tree.
10 | */
11 | class _04_09_BSTSequences {
12 |
13 | List> sequences(BinaryTreeNode root) {
14 | List> result = new ArrayList<>();
15 | if (root == null) {
16 | result.add(new LinkedList<>());
17 | return result;
18 | }
19 | LinkedList prefix = new LinkedList<>();
20 | prefix.add(root.val);
21 | List> leftSeqs = sequences(root.left);
22 | List> rightSeqs = sequences(root.right);
23 | for (LinkedList leftSeq : leftSeqs) {
24 | for (LinkedList rightSeq : rightSeqs) {
25 | List> weaved = new ArrayList<>();
26 | weave(leftSeq, rightSeq, weaved, prefix);
27 | result.addAll(weaved);
28 | }
29 | }
30 | return result;
31 | }
32 |
33 | private void weave(LinkedList first, LinkedList second, List> results, LinkedList prefix) {
34 | if (first.isEmpty() || second.isEmpty()) {
35 | LinkedList result = new LinkedList<>(prefix);
36 | result.addAll(first);
37 | result.addAll(second);
38 | results.add(result);
39 | return;
40 | }
41 |
42 | Integer headFirst = first.removeFirst();
43 | prefix.addLast(headFirst);
44 | weave(first, second, results, prefix);
45 | prefix.removeLast();
46 | first.addFirst(headFirst);
47 |
48 | Integer headSecond = second.removeFirst();
49 | prefix.addLast(headSecond);
50 | weave(first, second, results, prefix);
51 | prefix.removeLast();
52 | second.addFirst(headSecond);
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/src/main/java/treegraph/_04_10_CheckSubTree.java:
--------------------------------------------------------------------------------
1 | package treegraph;
2 |
3 | /**
4 | * T1 and T2 are two very large binary trees, with T1 much bigger than T2. Create an
5 | * algorithm to determine if T2 is a subtree of T1.
6 | *
7 | * A tree T2 is a subtree of T1 if there exists a node n in T1 such that the subtree of n is identical to T2.
8 | * That is, if you cut off the tree at node n, the two trees would be identical.
9 | */
10 | class _04_10_CheckSubTree {
11 |
12 | private StringBuilder sb;
13 |
14 | boolean isSubTree(BinaryTreeNode a, BinaryTreeNode b) {
15 | sb = new StringBuilder();
16 | preOrder(a);
17 | String preorderA = sb.toString();
18 | sb = new StringBuilder();
19 | preOrder(b);
20 | String preorderB = sb.toString();
21 | return preorderA.contains(preorderB);
22 | }
23 |
24 |
25 | private void preOrder(BinaryTreeNode a) {
26 | if (a == null) {
27 | sb.append('x');
28 | } else {
29 | sb.append(a.val);
30 | preOrder(a.left);
31 | preOrder(a.right);
32 | }
33 |
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/treegraph/_04_11_RandomNode.java:
--------------------------------------------------------------------------------
1 | package treegraph;
2 |
3 | import java.util.Random;
4 |
5 | /**
6 | * You are implementing a binary tree class from scratch
7 | * which, in addition to insert, find, and delete, has a method getRandomNode()
8 | * which returns a random node from the tree.
9 | *
10 | * All nodes should be equally likely to be chosen.
11 | * Design and implement an algorithm for getRandomNode,
12 | * and explain how you would implement the rest of the methods.
13 | */
14 | class _04_11_RandomNode {
15 |
16 | public static class Node {
17 | private int size = 1;
18 | private Node left;
19 | private Node right;
20 | private int val;
21 |
22 | Node(int val) {
23 | this.val = val;
24 | }
25 |
26 | void insert(int val) {
27 | if (val <= this.val) {
28 | if (left != null) {
29 | left.insert(val);
30 | } else {
31 | left = new Node(val);
32 | }
33 | } else {
34 | if (right != null) {
35 | right.insert(val);
36 | } else {
37 | right = new Node(val);
38 | }
39 | }
40 | size++;
41 | }
42 |
43 | Node find(int val) {
44 | if (val == this.val) {
45 | return this;
46 | } else if (val <= this.val) {
47 | return left == null ? null : left.find(val);
48 | } else {
49 | return right == null ? null : right.find(val);
50 | }
51 | }
52 |
53 | Node getIthNode(int i) {
54 | int leftSize = left == null ? 0 : left.size;
55 | if (i < leftSize) {
56 | return left.getIthNode(i);
57 | } else if (i == leftSize) {
58 | return this;
59 | } else {
60 | return right.getIthNode(i - left.size - 1);
61 | }
62 | }
63 |
64 | public int getVal() {
65 | return val;
66 | }
67 | }
68 |
69 | static class Tree {
70 | private Node root;
71 |
72 | void insert(int val) {
73 | if (root == null) root = new Node(val);
74 | root.insert(val);
75 | }
76 |
77 | Node find(int val) {
78 | return root == null ? null : root.find(val);
79 | }
80 |
81 | Node getRandomNode() {
82 | Random random = new Random();
83 | int i = random.nextInt(root.size);
84 | return root.getIthNode(i);
85 | }
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/main/java/treegraph/_04_12_PathsWithSum.java:
--------------------------------------------------------------------------------
1 | package treegraph;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | /**
7 | * You are given a binary tree in which each node contains an integer value (which might be positive or negative).
8 | * Design an algorithm to count the number of paths that target to a given value.
9 | * The path does not need to start or end at the root or a leaf, but it must go downwards
10 | * (traveling only from parent nodes to child nodes).
11 | */
12 | class _04_12_PathsWithSum {
13 |
14 |
15 | private int target;
16 | private Map runningSumToCount;
17 | private int count;
18 |
19 | int countPathWithSum(BinaryTreeNode node, int sum) {
20 | count = 0;
21 | runningSumToCount = new HashMap<>();
22 | runningSumToCount.put(0, 1);
23 | target = sum;
24 | countHelper(node, 0);
25 | return count;
26 | }
27 |
28 | private void countHelper(BinaryTreeNode node, int acc) {
29 | if (node == null) return;
30 | int runningSum = acc + node.val;
31 | runningSumToCount.merge(runningSum, 1, Math::addExact);
32 | count += runningSumToCount.getOrDefault(runningSum - target, 0);
33 | countHelper(node.left, runningSum);
34 | countHelper(node.right, runningSum);
35 | runningSumToCount.computeIfPresent(runningSum, (k, v) -> v == 1 ? null : v - 1);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/test/java/arraystring/_01_01_IsUniqueTest.java:
--------------------------------------------------------------------------------
1 | package arraystring;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertFalse;
6 | import static org.junit.Assert.assertTrue;
7 |
8 | public class _01_01_IsUniqueTest {
9 |
10 | private _01_01_IsUnique s = new _01_01_IsUnique();
11 |
12 | @Test
13 | public void withEmptyString() {
14 | assertTrue(s.isUnique(""));
15 | }
16 |
17 | @Test
18 | public void withUniqueString() {
19 | assertTrue(s.isUnique("abcde"));
20 | }
21 |
22 | @Test
23 | public void withDuplication() {
24 | assertFalse(s.isUnique("abcda"));
25 | }
26 |
27 | }
--------------------------------------------------------------------------------
/src/test/java/arraystring/_01_02_CheckPermutationTest.java:
--------------------------------------------------------------------------------
1 | package arraystring;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertFalse;
6 | import static org.junit.Assert.assertTrue;
7 |
8 | public class _01_02_CheckPermutationTest {
9 |
10 | private _01_02_CheckPermutation s = new _01_02_CheckPermutation();
11 |
12 | @Test
13 | public void withEmptyString() {
14 | assertTrue(s.check("", ""));
15 | }
16 |
17 | @Test
18 | public void withOneSingleChar() {
19 | assertTrue(s.check("a", "a"));
20 | }
21 |
22 | @Test
23 | public void withOneSingleDifferentChar() {
24 | assertFalse(s.check("a", "b"));
25 | }
26 |
27 | @Test
28 | public void withThreeChars() {
29 | assertTrue(s.check("abc", "bac"));
30 | }
31 |
32 | @Test
33 | public void withRepeatingChars() {
34 | assertTrue(s.check("aabbc", "bcaba"));
35 | }
36 |
37 | @Test
38 | public void withDifferentLength() {
39 | assertFalse(s.check("abc", "ab"));
40 | }
41 | }
--------------------------------------------------------------------------------
/src/test/java/arraystring/_01_03_URLifyTest.java:
--------------------------------------------------------------------------------
1 | package arraystring;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertArrayEquals;
6 |
7 | public class _01_03_URLifyTest {
8 |
9 | private _01_03_URLify s = new _01_03_URLify();
10 |
11 | @Test
12 | public void withNoSpace() {
13 | assertArrayEquals("hello".toCharArray(), s.urlify("hello".toCharArray(), 5));
14 | }
15 |
16 | @Test(expected = IllegalArgumentException.class)
17 | public void withInsufficientLength() {
18 | s.urlify("hello world ".toCharArray(), 11);
19 | }
20 |
21 | @Test
22 | public void withOneSpace() {
23 | assertArrayEquals("hello%20world".toCharArray(), s.urlify("hello world ".toCharArray(), 11));
24 | }
25 |
26 | @Test
27 | public void withTwoSpaces() {
28 | assertArrayEquals("hello%20world%20bob".toCharArray(), s.urlify("hello world bob ".toCharArray(), 15));
29 | }
30 | }
--------------------------------------------------------------------------------
/src/test/java/arraystring/_01_04_PalindromePermutationTest.java:
--------------------------------------------------------------------------------
1 | package arraystring;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertTrue;
6 |
7 | public class _01_04_PalindromePermutationTest {
8 |
9 | private _01_04_PalindromePermutation s = new _01_04_PalindromePermutation();
10 |
11 | @Test
12 | public void withEmpty() {
13 | assertTrue(s.check(""));
14 | }
15 |
16 | @Test
17 | public void withOneChar() {
18 | assertTrue(s.check("a"));
19 | }
20 |
21 | @Test
22 | public void withTwoWords_OddLetters() {
23 | assertTrue(s.check("acto tac"));
24 | }
25 |
26 | @Test
27 | public void withTwoWords_OddLetters_ThreeOccurences() {
28 | assertTrue(s.check("act atac"));
29 | }
30 |
31 | @Test
32 | public void withTwoWords_EvenLetters() {
33 | assertTrue(s.check("act cat"));
34 | }
35 | }
--------------------------------------------------------------------------------
/src/test/java/arraystring/_01_05_OneAwayTest.java:
--------------------------------------------------------------------------------
1 | package arraystring;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertFalse;
6 | import static org.junit.Assert.assertTrue;
7 |
8 | public class _01_05_OneAwayTest {
9 |
10 | private _01_05_OneAway s = new _01_05_OneAway();
11 |
12 | @Test
13 | public void withEmpty() {
14 | assertTrue(s.isOneAway("", ""));
15 | }
16 |
17 | @Test
18 | public void withOneEmpty() {
19 | assertTrue(s.isOneAway("", "b"));
20 | }
21 |
22 | @Test
23 | public void withTwoSingleWords() {
24 | assertTrue(s.isOneAway("a", "b"));
25 | }
26 |
27 | @Test
28 | public void withOneInsertion() {
29 | assertTrue(s.isOneAway("pae", "pale"));
30 | }
31 |
32 | @Test
33 | public void withOneDeletion() {
34 | assertTrue(s.isOneAway("pales", "paes"));
35 | }
36 |
37 | @Test
38 | public void withOneReplace() {
39 | assertTrue(s.isOneAway("pawe", "pave"));
40 | }
41 |
42 | @Test
43 | public void withMoreEdits() {
44 | assertFalse(s.isOneAway("paxye", "pamne"));
45 | }
46 | }
--------------------------------------------------------------------------------
/src/test/java/arraystring/_01_06_StringCompressionTest.java:
--------------------------------------------------------------------------------
1 | package arraystring;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertEquals;
6 |
7 | public class _01_06_StringCompressionTest {
8 |
9 | private _01_06_StringCompression s = new _01_06_StringCompression();
10 |
11 | @Test
12 | public void withOneSingleChar() {
13 | assertEquals("a", s.compress("a"));
14 | }
15 |
16 | @Test
17 | public void withTwoChars() {
18 | assertEquals("aa", s.compress("aa"));
19 | }
20 |
21 | @Test
22 | public void withThreeChars() {
23 | assertEquals("3a", s.compress("aaa"));
24 | }
25 |
26 | @Test
27 | public void withDifferentChars() {
28 | assertEquals("aaab", s.compress("aaab"));
29 | }
30 |
31 | @Test
32 | public void withDifferentChars_RepeatingSeveralTimes() {
33 | assertEquals("3a2b", s.compress("aaabb"));
34 | }
35 |
36 | @Test
37 | public void withDifferentChars_RepeatingInMoreSeqs() {
38 | assertEquals("3a2b2a", s.compress("aaabbaa"));
39 | }
40 |
41 | }
--------------------------------------------------------------------------------
/src/test/java/arraystring/_01_07_RotateMatrixTest.java:
--------------------------------------------------------------------------------
1 | package arraystring;
2 |
3 | import org.junit.Test;
4 |
5 | import java.util.Arrays;
6 |
7 | import static org.junit.Assert.assertTrue;
8 |
9 | public class _01_07_RotateMatrixTest {
10 |
11 | private _01_07_RotateMatrix s = new _01_07_RotateMatrix();
12 |
13 | @Test
14 | public void withOneOne() {
15 | assertTrue(Arrays.deepEquals(new int[][]{{1}}, s.rotate(new int[][]{{1}})));
16 | }
17 |
18 | @Test
19 | public void withTwoTwo() {
20 | assertTrue(Arrays.deepEquals(new int[][]{
21 | {3, 1},
22 | {4, 2}},
23 | s.rotate(new int[][]{
24 | {1, 2},
25 | {3, 4}})));
26 | }
27 |
28 | @Test
29 | public void withThreeThree() {
30 | assertTrue(Arrays.deepEquals(new int[][]{
31 | {7, 4, 1},
32 | {8, 5, 2},
33 | {9, 6, 3}
34 | },
35 | s.rotate(new int[][]{
36 | {1, 2, 3},
37 | {4, 5, 6},
38 | {7, 8, 9}})));
39 | }
40 | }
--------------------------------------------------------------------------------
/src/test/java/arraystring/_01_08_ZeroMatrixTest.java:
--------------------------------------------------------------------------------
1 | package arraystring;
2 |
3 | import org.junit.Test;
4 |
5 | import java.util.Arrays;
6 |
7 | import static org.junit.Assert.assertTrue;
8 |
9 | public class _01_08_ZeroMatrixTest {
10 |
11 | @Test
12 | public void withEmpty() {
13 | assertTrue(Arrays.deepEquals(new int[][]{{}}, new _01_08_ZeroMatrix().zero(new int[][]{{}})));
14 | }
15 |
16 |
17 | @Test
18 | public void withOneOne() {
19 | assertTrue(Arrays.deepEquals(new int[][]{{1}}, new _01_08_ZeroMatrix().zero(new int[][]{{1}})));
20 | }
21 |
22 | @Test
23 | public void withOneOne_Zero() {
24 | assertTrue(Arrays.deepEquals(new int[][]{{0}}, new _01_08_ZeroMatrix().zero(new int[][]{{0}})));
25 | }
26 |
27 | @Test
28 | public void withOneTwo() {
29 | assertTrue(Arrays.deepEquals(new int[][]{{0, 0}}, new _01_08_ZeroMatrix().zero(new int[][]{{0, 0}})));
30 | }
31 |
32 | @Test
33 | public void withTwoTwo() {
34 | assertTrue(Arrays.deepEquals(new int[][]{{0, 0}, {0, 1}}, new _01_08_ZeroMatrix().zero(new int[][]{{0, 1}, {1, 1}})));
35 | }
36 |
37 | @Test
38 | public void withThreeTree() {
39 | assertTrue(Arrays.deepEquals(
40 | new int[][]{
41 | {1, 0, 3},
42 | {0, 0, 0},
43 | {7, 0, 9}}, new _01_08_ZeroMatrix().zero(
44 | new int[][]{
45 | {1, 2, 3},
46 | {4, 0, 6},
47 | {7, 8, 9}})));
48 | }
49 | }
--------------------------------------------------------------------------------
/src/test/java/arraystring/_01_09_StringRotationTest.java:
--------------------------------------------------------------------------------
1 | package arraystring;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertFalse;
6 | import static org.junit.Assert.assertTrue;
7 |
8 | public class _01_09_StringRotationTest {
9 |
10 | private _01_09_StringRotation s = new _01_09_StringRotation();
11 |
12 | @Test
13 | public void withEmpty() {
14 | assertTrue(s.rotated("", ""));
15 | }
16 |
17 | @Test
18 | public void withSameWord() {
19 | assertTrue(s.rotated("hello", "hello"));
20 | }
21 |
22 | @Test
23 | public void withRotated() {
24 | assertTrue(s.rotated("hello", "llohe"));
25 | }
26 |
27 | @Test
28 | public void withSubstring_ButDifferentSize() {
29 | assertFalse(s.rotated("hello", "llo"));
30 | }
31 |
32 | @Test
33 | public void withDifferentWords() {
34 | assertFalse(s.rotated("hello", "world"));
35 | }
36 |
37 | @Test
38 | public void withNotRotated() {
39 | assertFalse(s.rotated("hello", "oehll"));
40 | }
41 |
42 | }
--------------------------------------------------------------------------------
/src/test/java/bitmanipulation/_05_01_InsertionTest.java:
--------------------------------------------------------------------------------
1 | package bitmanipulation;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertEquals;
6 |
7 | public class _05_01_InsertionTest {
8 |
9 | private _05_01_Insertion s = new _05_01_Insertion();
10 |
11 | @Test
12 | public void withZeros() {
13 | assertEquals(0, s.insert(0, 0, 2, 5));
14 | }
15 |
16 | @Test
17 | public void withLowInsertion() {
18 | int n = 0x00_00_69_00;
19 | int m = 0x00_00_00_b3;
20 | int x = 0x00_00_69_b3;
21 | int i = 0;
22 | int j = 7;
23 | assertEquals(x, s.insert(n, m, i, j));
24 | }
25 |
26 | @Test
27 | public void withHighInsertion() {
28 | int n = 0x00_00_69_00;
29 | int m = 0x00_00_00_b3;
30 | int x = 0x00_b3_69_00;
31 | int i = 16;
32 | int j = 23;
33 | assertEquals(x, s.insert(n, m, i, j));
34 | }
35 |
36 | @Test
37 | public void withMiddleInsertion() {
38 | int n = 0x00_00_69_00;
39 | int m = 0x00_00_00_b3;
40 | int x = 0x00_00_6b_30;
41 | int i = 4;
42 | int j = 11;
43 | assertEquals(x, s.insert(n, m, i, j));
44 | }
45 |
46 |
47 | }
--------------------------------------------------------------------------------
/src/test/java/bitmanipulation/_05_02_BinaryToStringTest.java:
--------------------------------------------------------------------------------
1 | package bitmanipulation;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertEquals;
6 |
7 | public class _05_02_BinaryToStringTest {
8 |
9 | private _05_02_BinaryToString s = new _05_02_BinaryToString();
10 |
11 | @Test
12 | public void withZero() {
13 | assertEquals("ERROR", s.print(0));
14 | }
15 |
16 | @Test
17 | public void withOne() {
18 | assertEquals("ERROR", s.print(1));
19 | }
20 |
21 | @Test
22 | public void withOneBit() {
23 | assertEquals(".1", s.print(0.5));
24 | }
25 |
26 | @Test
27 | public void withTwoBits() {
28 | assertEquals(".11", s.print(0.75));
29 | }
30 |
31 | @Test
32 | public void withThreeBits() {
33 | assertEquals(".101", s.print(0.625));
34 | }
35 |
36 | @Test
37 | public void withUndoable() {
38 | assertEquals("ERROR", s.print(0.1));
39 | }
40 |
41 | }
--------------------------------------------------------------------------------
/src/test/java/bitmanipulation/_05_03_FilpBitToWinTest.java:
--------------------------------------------------------------------------------
1 | package bitmanipulation;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertEquals;
6 |
7 | public class _05_03_FilpBitToWinTest {
8 |
9 | private _05_03_FlipBitToWin s = new _05_03_FlipBitToWin();
10 |
11 | @Test
12 | public void withZero() {
13 | assertEquals(1, s.flip(0));
14 | }
15 |
16 | @Test
17 | public void withAllOnes() {
18 | assertEquals(32, s.flip(-1));
19 | }
20 |
21 | @Test
22 | public void testWithOne() {
23 | assertEquals(2, s.flip(1));
24 | }
25 |
26 | @Test
27 | public void testWithOneSegment() {
28 | assertEquals(4, s.flip(0x0000_000b));
29 | }
30 |
31 | @Test
32 | public void testWithTwoSegments() {
33 | assertEquals(5, s.flip(0x00b8_000b));
34 | }
35 |
36 | @Test
37 | public void WithContinuesSegment() {
38 | assertEquals(8, s.flip(0x0000_F700));
39 | }
40 | }
--------------------------------------------------------------------------------
/src/test/java/bitmanipulation/_05_04_NextBiggerNumberTest.java:
--------------------------------------------------------------------------------
1 | package bitmanipulation;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertEquals;
6 |
7 | public class _05_04_NextBiggerNumberTest {
8 |
9 | private _05_04_NextBiggerNumber s = new _05_04_NextBiggerNumber();
10 |
11 | @Test
12 | public void withOne() {
13 | assertEquals(2, s.nextBigger(1));
14 | }
15 |
16 | @Test
17 | public void withIntegerTooBig() {
18 | assertEquals(-1, s.nextBigger(0x4000_0000));
19 | }
20 |
21 | @Test
22 | public void withTen() {
23 | assertEquals(12, s.nextBigger(10));
24 | }
25 |
26 | @Test
27 | public void withManyOnesZeros() {
28 | assertEquals(0x0008_ff03, s.nextBigger(0x0008_fee0));
29 | }
30 |
31 | }
--------------------------------------------------------------------------------
/src/test/java/bitmanipulation/_05_04_NextSmallerNumberTest.java:
--------------------------------------------------------------------------------
1 | package bitmanipulation;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertEquals;
6 |
7 | public class _05_04_NextSmallerNumberTest {
8 |
9 | private _05_04_NextSmallerNumber s = new _05_04_NextSmallerNumber();
10 |
11 | @Test
12 | public void withOne() {
13 | assertEquals(-1, s.nextSmaller(1));
14 | }
15 |
16 | @Test
17 | public void withIntegerTooSmall() {
18 | assertEquals(-1, s.nextSmaller(3));
19 | }
20 |
21 | @Test
22 | public void withTen() {
23 | assertEquals(9, s.nextSmaller(10));
24 | }
25 |
26 | @Test
27 | public void withManyOnesZeros() {
28 | assertEquals(0x0008_fee0, s.nextSmaller(0x0008_ff03));
29 | }
30 |
31 | }
--------------------------------------------------------------------------------
/src/test/java/bitmanipulation/_05_05_DebuggerTest.java:
--------------------------------------------------------------------------------
1 | package bitmanipulation;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertFalse;
6 | import static org.junit.Assert.assertTrue;
7 |
8 | public class _05_05_DebuggerTest {
9 |
10 | private _05_05_Debugger s = new _05_05_Debugger();
11 |
12 | @Test
13 | public void withZero() {
14 | assertTrue(s.debug(0));
15 | }
16 |
17 | @Test
18 | public void withOne() {
19 | assertTrue(s.debug(1));
20 | }
21 |
22 | @Test
23 | public void withTwo() {
24 | assertTrue(s.debug(2));
25 | }
26 |
27 | @Test
28 | public void withThree() {
29 | assertFalse(s.debug(3));
30 | }
31 |
32 | @Test
33 | public void withFour() {
34 | assertTrue(s.debug(4));
35 | }
36 |
37 | @Test
38 | public void withFive() {
39 | assertFalse(s.debug(5));
40 | }
41 |
42 | }
--------------------------------------------------------------------------------
/src/test/java/bitmanipulation/_05_06_ConversionTest.java:
--------------------------------------------------------------------------------
1 | package bitmanipulation;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertEquals;
6 |
7 | public class _05_06_ConversionTest {
8 |
9 | private _05_06_Conversion s = new _05_06_Conversion();
10 |
11 | @Test
12 | public void withZeroAndOne() {
13 | assertEquals(1, s.convert(0, 1));
14 | }
15 |
16 | @Test
17 | public void withOneAndOne() {
18 | assertEquals(0, s.convert(1, 1));
19 | }
20 |
21 | @Test
22 | public void withOneAndTwo() {
23 | assertEquals(2, s.convert(1, 2));
24 | }
25 |
26 | @Test
27 | public void withZeroAndThree() {
28 | assertEquals(2, s.convert(0, 3));
29 | }
30 | }
--------------------------------------------------------------------------------
/src/test/java/bitmanipulation/_05_07_PairwiseSwapTest.java:
--------------------------------------------------------------------------------
1 | package bitmanipulation;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertEquals;
6 |
7 | public class _05_07_PairwiseSwapTest {
8 |
9 | private _05_07_PairwiseSwap s = new _05_07_PairwiseSwap();
10 |
11 | @Test
12 | public void withZero() {
13 | assertEquals(0, s.swap(0));
14 | }
15 |
16 | @Test
17 | public void withOne() {
18 | assertEquals(2, s.swap(1));
19 | }
20 |
21 | @Test
22 | public void withTwo() {
23 | assertEquals(1, s.swap(2));
24 | }
25 |
26 | @Test
27 | public void withTen() {
28 | assertEquals(5, s.swap(10));
29 | }
30 |
31 | @Test
32 | public void withTenEveryWhere() {
33 | assertEquals(0x5555_5555, s.swap(0xaaaa_aaaa));
34 | }
35 | }
--------------------------------------------------------------------------------
/src/test/java/bitmanipulation/_05_08_DrawLineTest.java:
--------------------------------------------------------------------------------
1 | package bitmanipulation;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertArrayEquals;
6 |
7 | public class _05_08_DrawLineTest {
8 |
9 | private _05_08_DrawLine s = new _05_08_DrawLine();
10 |
11 | @Test
12 | public void with1Row8Columns_DrawEntireLine() {
13 | assertArrayEquals(new byte[]{(byte) 0xff}, s.drawLine(new byte[]{0}, 8, 0, 7, 0));
14 | }
15 |
16 | @Test
17 | public void with1Row8Columns_DrawSubLine() {
18 | assertArrayEquals(new byte[]{(byte) 0x7e}, s.drawLine(new byte[]{0}, 8, 1, 6, 0));
19 | }
20 |
21 | @Test
22 | public void with1Row8Columns_DrawSubLine_SomeBitsAlreadySet() {
23 | assertArrayEquals(new byte[]{(byte) 0xfe}, s.drawLine(new byte[]{(byte) 0x80}, 8, 1, 6, 0));
24 | }
25 |
26 | @Test
27 | public void with1Row16Columns() {
28 | assertArrayEquals(new byte[]{(byte) 0x03, (byte) 0xfc}, s.drawLine(new byte[]{0, 0}, 16, 6, 13, 0));
29 | }
30 |
31 | @Test
32 | public void with2Row16Columns() {
33 | assertArrayEquals(new byte[]{0, 0, (byte) 0x03, (byte) 0xfc}, s.drawLine(new byte[]{0, 0, 0, 0}, 16, 6, 13, 1));
34 | }
35 | }
--------------------------------------------------------------------------------
/src/test/java/linkedlist/_02_01_RemoveDupsTest.java:
--------------------------------------------------------------------------------
1 | package linkedlist;
2 |
3 | import org.junit.Assert;
4 | import org.junit.Test;
5 |
6 | public class _02_01_RemoveDupsTest {
7 |
8 | private _02_01_RemoveDups s = new _02_01_RemoveDups();
9 |
10 | @Test
11 | public void withEmptyList() {
12 | Assert.assertEquals(LinkedListNode.empty(), s.removeDups(LinkedListNode.empty()));
13 | }
14 |
15 | @Test
16 | public void withUniqueList() {
17 | Assert.assertEquals(LinkedListNode.of(1, 2, 3, 4), s.removeDups(LinkedListNode.of(1, 2, 3, 4)));
18 | }
19 |
20 | @Test
21 | public void withDuplications() {
22 | Assert.assertEquals(LinkedListNode.of(1, 2, 3, 4), s.removeDups(LinkedListNode.of(1, 2, 2, 3, 2, 4)));
23 | }
24 |
25 | }
--------------------------------------------------------------------------------
/src/test/java/linkedlist/_02_02_ReturnKthToLastTest.java:
--------------------------------------------------------------------------------
1 | package linkedlist;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertEquals;
6 | import static org.junit.Assert.assertNull;
7 |
8 | public class _02_02_ReturnKthToLastTest {
9 |
10 | private _02_02_ReturnKthToLast s = new _02_02_ReturnKthToLast();
11 |
12 | @Test
13 | public void withOutOfScopeK() {
14 | assertNull(s.kthToLast(LinkedListNode.of(1, 2, 3), 3));
15 | }
16 |
17 | @Test
18 | public void withZero() {
19 | assertEquals(3, s.kthToLast(LinkedListNode.of(1, 2, 3), 0).val);
20 | }
21 |
22 | @Test
23 | public void withNoneZero() {
24 | assertEquals(2, s.kthToLast(LinkedListNode.of(1, 2, 3), 1).val);
25 | }
26 |
27 |
28 | }
--------------------------------------------------------------------------------
/src/test/java/linkedlist/_02_03_DeleteMiddleNodeTest.java:
--------------------------------------------------------------------------------
1 | package linkedlist;
2 |
3 | import org.junit.Assert;
4 | import org.junit.Test;
5 |
6 | import static org.junit.Assert.assertFalse;
7 | import static org.junit.Assert.assertTrue;
8 |
9 | public class _02_03_DeleteMiddleNodeTest {
10 |
11 | private _02_03_DeleteMiddleNode s = new _02_03_DeleteMiddleNode();
12 |
13 | @Test
14 | public void withNull() {
15 | assertFalse(s.deleteMiddleNode(null));
16 | }
17 |
18 | @Test
19 | public void withLastNode() {
20 | assertFalse(s.deleteMiddleNode(LinkedListNode.of(1, 2, 3).next.next));
21 | }
22 |
23 | @Test
24 | public void withMiddleNode() {
25 | LinkedListNode input = LinkedListNode.of(1, 2, 3);
26 | assertTrue(s.deleteMiddleNode(input.next));
27 | Assert.assertEquals(LinkedListNode.of(1, 3), input);
28 | }
29 |
30 | }
--------------------------------------------------------------------------------
/src/test/java/linkedlist/_02_04_PartitionTest.java:
--------------------------------------------------------------------------------
1 | package linkedlist;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertEquals;
6 |
7 | public class _02_04_PartitionTest {
8 |
9 | private _02_04_Partition s = new _02_04_Partition();
10 |
11 | @Test
12 | public void withEmptyList() {
13 | assertEquals(LinkedListNode.empty(), s.partition(LinkedListNode.empty(), 8));
14 | }
15 |
16 | @Test
17 | public void withSortedList() {
18 | assertEquals(LinkedListNode.of(1, 2, 3), s.partition(LinkedListNode.of(1, 2, 3), 2));
19 | }
20 |
21 | @Test
22 | public void withSortedList_AndOutOfListX() {
23 | assertEquals(LinkedListNode.of(3, 2, 1), s.partition(LinkedListNode.of(1, 2, 3), 4));
24 | }
25 |
26 | @Test
27 | public void withSortedList_AndOutOfListX_Smaller() {
28 | assertEquals(LinkedListNode.of(1, 2, 3), s.partition(LinkedListNode.of(1, 2, 3), 0));
29 | }
30 |
31 | @Test
32 | public void withUnSortedList() {
33 | assertEquals(LinkedListNode.of(1, 2, 4, 3, 5), s.partition(LinkedListNode.of(4, 3, 2, 5, 1), 3));
34 | }
35 |
36 | @Test
37 | public void withUnSortedList_AndOutOfScopeX() {
38 | assertEquals(LinkedListNode.of(1, 2, 4, 3, 6), s.partition(LinkedListNode.of(3, 4, 2, 6, 1), 5));
39 | }
40 |
41 | }
--------------------------------------------------------------------------------
/src/test/java/linkedlist/_02_05_SumListReverseTest.java:
--------------------------------------------------------------------------------
1 | package linkedlist;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertEquals;
6 |
7 | public class _02_05_SumListReverseTest {
8 |
9 | private _02_05_SumListReverse s = new _02_05_SumListReverse();
10 |
11 | @Test
12 | public void withTwoEmptyLists() {
13 | assertEquals(LinkedListNode.empty(), s.sum(LinkedListNode.empty(), LinkedListNode.empty()));
14 | }
15 |
16 | @Test
17 | public void withOneEmptyList() {
18 | assertEquals(LinkedListNode.of(1, 2, 3), s.sum(LinkedListNode.empty(), LinkedListNode.of(1, 2, 3)));
19 | }
20 |
21 | @Test
22 | public void withNoCarry() {
23 | assertEquals(LinkedListNode.of(2, 4, 6), s.sum(LinkedListNode.of(1, 2, 3), LinkedListNode.of(1, 2, 3)));
24 | }
25 |
26 | @Test
27 | public void withCarry() {
28 | assertEquals(LinkedListNode.of(0, 4, 6), s.sum(LinkedListNode.of(1, 8, 3), LinkedListNode.of(9, 5, 2)));
29 | }
30 |
31 | @Test
32 | public void withCarryAtEnd() {
33 | assertEquals(LinkedListNode.of(0, 4, 2, 1), s.sum(LinkedListNode.of(1, 8, 9), LinkedListNode.of(9, 5, 2)));
34 | }
35 | }
--------------------------------------------------------------------------------
/src/test/java/linkedlist/_02_05_SumListTest.java:
--------------------------------------------------------------------------------
1 | package linkedlist;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertEquals;
6 |
7 | public class _02_05_SumListTest {
8 |
9 | private _02_05_SumList s = new _02_05_SumList();
10 |
11 | @Test
12 | public void withTwoEmptyLists() {
13 | assertEquals(LinkedListNode.empty(), s.sum(LinkedListNode.empty(), LinkedListNode.empty()));
14 | }
15 |
16 | @Test
17 | public void withOneEmptyList() {
18 | assertEquals(LinkedListNode.of(1, 2, 3), s.sum(LinkedListNode.empty(), LinkedListNode.of(1, 2, 3)));
19 | }
20 |
21 | @Test
22 | public void withNoCarry() {
23 | assertEquals(LinkedListNode.of(2, 4, 6), s.sum(LinkedListNode.of(1, 2, 3), LinkedListNode.of(1, 2, 3)));
24 | }
25 |
26 | @Test
27 | public void withCarry() {
28 | assertEquals(LinkedListNode.of(5, 3, 5), s.sum(LinkedListNode.of(1, 8, 3), LinkedListNode.of(3, 5, 2)));
29 | }
30 |
31 | @Test
32 | public void withCarryAtEnd() {
33 | assertEquals(LinkedListNode.of(1, 1, 4, 1), s.sum(LinkedListNode.of(1, 8, 9), LinkedListNode.of(9, 5, 2)));
34 | }
35 |
36 | @Test
37 | public void withTwoListsHavingDiffrentLength() {
38 | assertEquals(LinkedListNode.of(2, 4, 1), s.sum(LinkedListNode.of(1, 8, 9), LinkedListNode.of(5, 2)));
39 | }
40 | }
--------------------------------------------------------------------------------
/src/test/java/linkedlist/_02_06_PalindromeTest.java:
--------------------------------------------------------------------------------
1 | package linkedlist;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertFalse;
6 | import static org.junit.Assert.assertTrue;
7 |
8 | public class _02_06_PalindromeTest {
9 |
10 | private _02_06_Palindrome s = new _02_06_Palindrome();
11 |
12 | @Test
13 | public void withEmptyList() {
14 | assertTrue(s.isPalindrome(LinkedListNode.empty()));
15 | }
16 |
17 | @Test
18 | public void withOneElement() {
19 | assertTrue(s.isPalindrome(LinkedListNode.of(1)));
20 | }
21 |
22 | @Test
23 | public void withThreeElements() {
24 | assertTrue(s.isPalindrome(LinkedListNode.of(1, 2, 1)));
25 | }
26 |
27 | @Test
28 | public void withFourElements() {
29 | assertTrue(s.isPalindrome(LinkedListNode.of(1, 2, 2, 1)));
30 | }
31 |
32 | @Test
33 | public void withFourElements_NotPalindrome() {
34 | assertFalse(s.isPalindrome(LinkedListNode.of(1, 2, 2, 3)));
35 | }
36 | }
--------------------------------------------------------------------------------
/src/test/java/linkedlist/_02_07_IntersectionTest.java:
--------------------------------------------------------------------------------
1 | package linkedlist;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertFalse;
6 | import static org.junit.Assert.assertTrue;
7 |
8 | public class _02_07_IntersectionTest {
9 |
10 | private _02_07_Intersection s = new _02_07_Intersection();
11 |
12 | @Test
13 | public void withTwoEmptyLists() {
14 | assertFalse(s.intersects(LinkedListNode.empty(), LinkedListNode.empty()));
15 | }
16 |
17 | @Test
18 | public void withOneEmptyList() {
19 | assertFalse(s.intersects(LinkedListNode.empty(), LinkedListNode.of(1, 2, 3)));
20 | assertFalse(s.intersects(LinkedListNode.of(1, 2, 3), LinkedListNode.empty()));
21 | }
22 |
23 | @Test
24 | public void withTwoSeparatedLists() {
25 | assertFalse(s.intersects(LinkedListNode.of(1, 2, 3), LinkedListNode.of(4, 5, 6)));
26 | }
27 |
28 | @Test
29 | public void withTwoSeparatedLists_HavingSameValue() {
30 | assertFalse(s.intersects(LinkedListNode.of(1, 2, 3), LinkedListNode.of(4, 2, 3)));
31 | }
32 |
33 | @Test
34 | public void withIntersectedLists() {
35 | LinkedListNode l1 = LinkedListNode.of(1, 2, 3, 4, 5);
36 | LinkedListNode l2 = LinkedListNode.of(6, 7, 8);
37 | l2.next.next.next = l1.next;
38 | assertTrue(s.intersects(l1, l2));
39 | }
40 | }
--------------------------------------------------------------------------------
/src/test/java/linkedlist/_02_08_LoopDetectionTest.java:
--------------------------------------------------------------------------------
1 | package linkedlist;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertEquals;
6 | import static org.junit.Assert.assertNull;
7 |
8 | public class _02_08_LoopDetectionTest {
9 |
10 | private _02_08_LoopDetection s = new _02_08_LoopDetection();
11 |
12 | @Test
13 | public void withEmptyList() {
14 | assertNull(s.detect(LinkedListNode.empty()));
15 | }
16 |
17 | @Test
18 | public void withListWithoutLoop() {
19 | assertNull(s.detect(LinkedListNode.of(1, 2, 3)));
20 | }
21 |
22 | @Test
23 | public void testWithLoop_FromListHead() {
24 | LinkedListNode list = LinkedListNode.of(1, 2, 3, 4, 5);
25 | list.next.next.next.next.next = list;
26 | assertEquals(1, s.detect(list).val);
27 | }
28 |
29 | @Test
30 | public void testWithLoop_FromListTail() {
31 | LinkedListNode list = LinkedListNode.of(1, 2, 3, 4, 5);
32 | LinkedListNode tail = list.next.next.next.next;
33 | tail.next = tail;
34 | assertEquals(5, s.detect(list).val);
35 | }
36 |
37 | @Test
38 | public void testWithLoop_FromListMiddle() {
39 | LinkedListNode list = LinkedListNode.of(1, 2, 3, 4, 5);
40 | list.next.next.next.next.next = list.next;
41 | assertEquals(2, s.detect(list).val);
42 | }
43 | }
--------------------------------------------------------------------------------
/src/test/java/moderate/_16_01_NumberSwapperTest.java:
--------------------------------------------------------------------------------
1 | package moderate;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertEquals;
6 |
7 | public class _16_01_NumberSwapperTest {
8 |
9 | private _16_01_NumberSwapper s = new _16_01_NumberSwapper();
10 |
11 | @Test
12 | public void test() {
13 | int[] ab = {1, 2};
14 | s.swap(ab);
15 | assertEquals(ab[0], 2);
16 | assertEquals(ab[1], 1);
17 | }
18 |
19 | }
--------------------------------------------------------------------------------
/src/test/java/moderate/_16_06_SmallestDifferenceTest.java:
--------------------------------------------------------------------------------
1 | package moderate;
2 |
3 | import org.junit.Assert;
4 | import org.junit.Test;
5 |
6 | public class _16_06_SmallestDifferenceTest {
7 |
8 | private _16_06_SmallestDifference s = new _16_06_SmallestDifference();
9 |
10 | @Test
11 | public void withOneValueEach() {
12 | Assert.assertEquals(1, s.findSmallestDiff(new int[]{1}, new int[]{2}));
13 | }
14 |
15 | @Test
16 | public void withOneValueLeft_TwoValuesRight() {
17 | Assert.assertEquals(1, s.findSmallestDiff(new int[]{5}, new int[]{3, 6}));
18 | }
19 |
20 | @Test
21 | public void withMultipleValuesEach() {
22 | Assert.assertEquals(3, s.findSmallestDiff(new int[]{1, 3, 15, 11, 2}, new int[]{23, 127, 235, 19, 8}));
23 | }
24 | }
--------------------------------------------------------------------------------
/src/test/java/recursivedp/_08_01_TripleStepTest.java:
--------------------------------------------------------------------------------
1 | package recursivedp;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertEquals;
6 |
7 | public class _08_01_TripleStepTest {
8 |
9 | private _08_01_TripleStep s = new _08_01_TripleStep();
10 |
11 | @Test
12 | public void withZeroStep() {
13 | assertEquals(1, s.countWays(0));
14 | }
15 |
16 | @Test
17 | public void withOneStep() {
18 | assertEquals(1, s.countWays(1));
19 | }
20 |
21 | @Test
22 | public void withTwoSteps() {
23 | assertEquals(2, s.countWays(2));
24 | }
25 |
26 | @Test
27 | public void withTreeSteps() {
28 | assertEquals(4, s.countWays(3));
29 | }
30 |
31 | @Test
32 | public void withFourSteps() {
33 | //3+1
34 | // 3
35 | // 2+1
36 | // 1+2
37 | // 1+1+1
38 | //2+2
39 | // 2
40 | // 1+1
41 | //1+3
42 | // 1
43 | assertEquals(7, s.countWays(4));
44 | }
45 |
46 | @Test
47 | public void withFiveSteps() {
48 | assertEquals(13, s.countWays(5));
49 | }
50 |
51 | }
--------------------------------------------------------------------------------
/src/test/java/recursivedp/_08_02_RobotInAGridTest.java:
--------------------------------------------------------------------------------
1 | package recursivedp;
2 |
3 | import org.junit.Test;
4 |
5 | import java.awt.*;
6 | import java.util.Arrays;
7 | import java.util.Collections;
8 |
9 | import static org.junit.Assert.assertEquals;
10 |
11 | public class _08_02_RobotInAGridTest {
12 |
13 |
14 | private _08_02_RobotInAGrid s = new _08_02_RobotInAGrid();
15 |
16 | @Test
17 | public void withAllFeasibleCells() {
18 | boolean[][] grid = new boolean[][]{
19 | {true, true, true},
20 | {true, true, true},
21 | {true, true, true}
22 | };
23 |
24 | assertEquals(Arrays.asList(
25 | new Point(0, 0), new Point(0, 1),
26 | new Point(0, 2), new Point(1, 2),
27 | new Point(2, 2)), s.findPath(grid));
28 | }
29 |
30 | @Test
31 | public void withSomeBrokenCells() {
32 | boolean[][] grid = new boolean[][]{
33 | {true, true, true},
34 | {true, true, false},
35 | {false, true, true}
36 | };
37 |
38 | assertEquals(Arrays.asList(
39 | new Point(0, 0), new Point(0, 1),
40 | new Point(1, 1), new Point(2, 1),
41 | new Point(2, 2)), s.findPath(grid));
42 | }
43 |
44 | @Test
45 | public void withNoPath() {
46 | boolean[][] grid = new boolean[][]{
47 | {true, true, true},
48 | {true, true, false},
49 | {false, false, true}
50 | };
51 |
52 | assertEquals(Collections.emptyList(), s.findPath(grid));
53 | }
54 |
55 |
56 | }
--------------------------------------------------------------------------------
/src/test/java/recursivedp/_08_03_MagicIndexTest.java:
--------------------------------------------------------------------------------
1 | package recursivedp;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertEquals;
6 |
7 | public class _08_03_MagicIndexTest {
8 |
9 | private _08_03_MagicIndex s = new _08_03_MagicIndex();
10 |
11 | @Test
12 | public void withOneElement() {
13 | assertEquals(-1, s.findMagicIndex(new int[]{2}));
14 | assertEquals(0, s.findMagicIndex(new int[]{0}));
15 | }
16 |
17 | @Test
18 | public void withMagicIndex() {
19 | assertEquals(2, s.findMagicIndex(new int[]{-1, 0, 2, 5, 7, 9}));
20 | }
21 |
22 | @Test
23 | public void withoutMagicIndex() {
24 | assertEquals(-1, s.findMagicIndex(new int[]{1, 2, 3, 4, 5, 6}));
25 | }
26 | }
--------------------------------------------------------------------------------
/src/test/java/recursivedp/_08_04_PowerSetTest.java:
--------------------------------------------------------------------------------
1 | package recursivedp;
2 |
3 | import org.junit.Test;
4 |
5 | import java.util.Arrays;
6 | import java.util.Collections;
7 | import java.util.HashSet;
8 | import java.util.Set;
9 |
10 | import static org.junit.Assert.assertEquals;
11 |
12 | public class _08_04_PowerSetTest {
13 |
14 | private _08_04_PowerSet s = new _08_04_PowerSet();
15 |
16 | @Test
17 | public void withEmptySet() {
18 | assertEquals(Collections.emptySet(), s.subSets(Collections.emptySet()));
19 | }
20 |
21 | @Test
22 | public void withOneElement() {
23 | Set> subsets = new HashSet<>();
24 | subsets.add(Collections.emptySet());
25 | subsets.add(Collections.singleton(1));
26 | assertEquals(subsets, s.subSets(Collections.singleton(1)));
27 | }
28 |
29 | @Test
30 | public void withTwoElements() {
31 | Set> subsets = new HashSet<>();
32 | subsets.add(Collections.emptySet());
33 | subsets.add(Collections.singleton(1));
34 | subsets.add(Collections.singleton(2));
35 | subsets.add(new HashSet<>(Arrays.asList(1, 2)));
36 | assertEquals(subsets, s.subSets(new HashSet<>(Arrays.asList(1, 2))));
37 | }
38 | }
--------------------------------------------------------------------------------
/src/test/java/recursivedp/_08_05_RecursiveMultiplyTest.java:
--------------------------------------------------------------------------------
1 | package recursivedp;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertEquals;
6 |
7 | public class _08_05_RecursiveMultiplyTest {
8 |
9 | private _08_05_RecursiveMultiply s = new _08_05_RecursiveMultiply();
10 |
11 | @Test
12 | public void testOneOne() {
13 | assertEquals(1, s.multiple(1, 1));
14 | }
15 |
16 | @Test
17 | public void testOneTwo() {
18 | assertEquals(2, s.multiple(1, 2));
19 | }
20 |
21 | @Test
22 | public void testFiveNine() {
23 | assertEquals(45, s.multiple(5, 9));
24 | }
25 |
26 | @Test
27 | public void testThirtyForty() {
28 | assertEquals(1200, s.multiple(40, 30));
29 | }
30 | }
--------------------------------------------------------------------------------
/src/test/java/recursivedp/_08_06_HanoiTowersTest.java:
--------------------------------------------------------------------------------
1 | package recursivedp;
2 |
3 | import org.junit.Test;
4 |
5 | import java.util.Arrays;
6 |
7 | import static org.junit.Assert.assertEquals;
8 |
9 | public class _08_06_HanoiTowersTest {
10 |
11 | private _08_06_HanoiTowers s = new _08_06_HanoiTowers();
12 |
13 | @Test
14 | public void withOneDisk() {
15 | assertEquals(Arrays.asList(1, 3), s.leftToRight(1));
16 | }
17 |
18 | @Test
19 | public void withTwoDisk() {
20 | assertEquals(Arrays.asList(
21 | 1, 2,
22 | 1, 3,
23 | 2, 3
24 | ), s.leftToRight(2));
25 | }
26 |
27 | @Test
28 | public void withThreeDisks() {
29 | assertEquals(Arrays.asList(
30 | 1, 3,
31 | 1, 2,
32 | 3, 2,
33 | 1, 3,
34 | 2, 1,
35 | 2, 3,
36 | 1, 3
37 | ), s.leftToRight(3));
38 | }
39 | }
--------------------------------------------------------------------------------
/src/test/java/recursivedp/_08_07_PermutationWithoutDupTest.java:
--------------------------------------------------------------------------------
1 | package recursivedp;
2 |
3 | import org.junit.Test;
4 |
5 | import java.util.Arrays;
6 | import java.util.Collections;
7 | import java.util.HashSet;
8 |
9 | import static org.junit.Assert.assertEquals;
10 |
11 | public class _08_07_PermutationWithoutDupTest {
12 |
13 | private _08_07_PermutationWithoutDup s = new _08_07_PermutationWithoutDup();
14 |
15 | @Test
16 | public void withEmptyString() {
17 | assertEquals(Collections.singleton(""), s.computePermutation(""));
18 | }
19 |
20 | @Test
21 | public void withOneChar() {
22 | assertEquals(Collections.singleton("a"), s.computePermutation("a"));
23 | }
24 |
25 | @Test
26 | public void withTwoChars() {
27 | assertEquals(new HashSet<>(Arrays.asList("ab", "ba")), s.computePermutation("ab"));
28 | assertEquals(new HashSet<>(Arrays.asList("ab", "ba")), s.computePermutation("ba"));
29 | }
30 |
31 | @Test
32 | public void withThreeChars() {
33 | HashSet result = new HashSet<>(Arrays.asList("abc", "acb", "bca", "bac", "cab", "cba"));
34 | assertEquals(result, s.computePermutation("abc"));
35 | assertEquals(result, s.computePermutation("acb"));
36 | assertEquals(result, s.computePermutation("bca"));
37 | }
38 |
39 | }
--------------------------------------------------------------------------------
/src/test/java/recursivedp/_08_08_PermutationWithDupTest.java:
--------------------------------------------------------------------------------
1 | package recursivedp;
2 |
3 | import org.junit.Test;
4 |
5 | import java.util.Arrays;
6 | import java.util.Collections;
7 | import java.util.HashSet;
8 |
9 | import static org.junit.Assert.assertEquals;
10 |
11 | public class _08_08_PermutationWithDupTest {
12 |
13 | private _08_08_PermutationWithDup s = new _08_08_PermutationWithDup();
14 |
15 | @Test
16 | public void withEmptyString() {
17 | assertEquals(Collections.singleton(""), s.computePermutation(""));
18 | }
19 |
20 | @Test
21 | public void withOneChar() {
22 | assertEquals(Collections.singleton("a"), s.computePermutation("a"));
23 | }
24 |
25 | @Test
26 | public void withTwoChars() {
27 | assertEquals(Collections.singleton("aa"), s.computePermutation("aa"));
28 | }
29 |
30 | @Test
31 | public void withThreeChars() {
32 | HashSet result = new HashSet<>(Arrays.asList("aab", "aba", "baa"));
33 | assertEquals(result, s.computePermutation("aba"));
34 | }
35 |
36 | @Test
37 | public void withManySameChar() {
38 | String str = "aaaaaaaaaaaa";
39 | assertEquals(Collections.singleton(str), s.computePermutation(str));
40 | }
41 |
42 | }
--------------------------------------------------------------------------------
/src/test/java/recursivedp/_08_09_ParensTest.java:
--------------------------------------------------------------------------------
1 | package recursivedp;
2 |
3 | import org.junit.Assert;
4 | import org.junit.Test;
5 |
6 | import java.util.Arrays;
7 | import java.util.Collections;
8 | import java.util.HashSet;
9 |
10 | public class _08_09_ParensTest {
11 |
12 | private final _08_09_Parens s = new _08_09_Parens();
13 |
14 | @Test
15 | public void withZeroPair() {
16 | Assert.assertEquals(Collections.emptySet(), s.combine(0));
17 | }
18 |
19 | @Test
20 | public void withOnePair() {
21 | Assert.assertEquals(Collections.singleton("()"), s.combine(1));
22 | }
23 |
24 | @Test
25 | public void withTwoPairs() {
26 | Assert.assertEquals(new HashSet<>(Arrays.asList("()()", "(())")), s.combine(2));
27 | }
28 |
29 | @Test
30 | public void withThreePairs() {
31 | Assert.assertEquals(new HashSet<>(Arrays.asList(
32 | "((()))",
33 | "(()())",
34 | "(())()",
35 | "()(())",
36 | "()()()")), s.combine(3));
37 | }
38 | }
--------------------------------------------------------------------------------
/src/test/java/recursivedp/_08_10_PaintFillTest.java:
--------------------------------------------------------------------------------
1 | package recursivedp;
2 |
3 | import org.junit.Assert;
4 | import org.junit.Test;
5 |
6 | import java.util.Arrays;
7 |
8 | public class _08_10_PaintFillTest {
9 |
10 | private final _08_10_PaintFill s = new _08_10_PaintFill();
11 |
12 | @Test
13 | public void withAllOriginalColorConnected() {
14 | int[][] screen = new int[][]{
15 | {1, 0, 1},
16 | {0, 0, 1},
17 | {1, 0, 0}
18 | };
19 |
20 | int x = 1, y = 1;
21 |
22 | int newColor = 2;
23 |
24 | int[][] expected = new int[][]{
25 | {1, 2, 1},
26 | {2, 2, 1},
27 | {1, 2, 2}
28 | };
29 | Assert.assertTrue(Arrays.deepEquals(expected, s.paintFill(screen, x, y, newColor)));
30 | }
31 |
32 | @Test
33 | public void withAllOriginalColorSeparated() {
34 | int[][] screen = new int[][]{
35 | {1, 0, 1},
36 | {0, 1, 1},
37 | {1, 0, 0}
38 | };
39 |
40 | int x = 2, y = 1;
41 |
42 | int newColor = 2;
43 |
44 | int[][] expected = new int[][]{
45 | {1, 0, 1},
46 | {0, 1, 1},
47 | {1, 2, 2}
48 | };
49 | Assert.assertTrue(Arrays.deepEquals(expected, s.paintFill(screen, x, y, newColor)));
50 | }
51 | }
--------------------------------------------------------------------------------
/src/test/java/recursivedp/_08_11_CoinsTest.java:
--------------------------------------------------------------------------------
1 | package recursivedp;
2 |
3 | import org.junit.Assert;
4 | import org.junit.Test;
5 |
6 | public class _08_11_CoinsTest {
7 |
8 | private final _08_11_Coins s = new _08_11_Coins();
9 |
10 | @Test
11 | public void withZeroCent() {
12 | Assert.assertEquals(1, s.makeChangeWithQuarterDimeNickelPenny(0));
13 | }
14 |
15 | @Test
16 | public void withOneCent() {
17 | Assert.assertEquals(1, s.makeChangeWithQuarterDimeNickelPenny(2));
18 | }
19 |
20 | @Test
21 | public void withTwoCents() {
22 | Assert.assertEquals(1, s.makeChangeWithQuarterDimeNickelPenny(3));
23 | }
24 |
25 | @Test
26 | public void with25Cents() {
27 | //25
28 | //10 10 5
29 | //10 10 1 1 1 1 1
30 | //10 5 5 5
31 | //10 5 5 1 1 1 1 1
32 | //10 5 1 1 1 1 1 1 1 1 1 1
33 | //10 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
34 | //5 5 5 5 5
35 | //5 5 5 5 1 1 1 1 1
36 | //5 5 5 1 1 1 1 1 1 1 1 1 1
37 | //5 5 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
38 | //5 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
39 | //1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
40 | Assert.assertEquals(13, s.makeChangeWithQuarterDimeNickelPenny(25));
41 | }
42 |
43 | @Test
44 | public void with100Cents() {
45 | Assert.assertEquals(242, s.makeChangeWithQuarterDimeNickelPenny(100));
46 | }
47 |
48 | }
--------------------------------------------------------------------------------
/src/test/java/recursivedp/_08_12_EightQueensTest.java:
--------------------------------------------------------------------------------
1 | package recursivedp;
2 |
3 | import org.junit.Assert;
4 | import org.junit.Test;
5 |
6 | import java.awt.*;
7 | import java.util.List;
8 | import java.util.stream.Collectors;
9 |
10 | public class _08_12_EightQueensTest {
11 |
12 | private final _08_12_EightQueens s = new _08_12_EightQueens();
13 |
14 | @Test
15 | public void withEightQueens() {
16 | List> result = s.arrange();
17 | System.out.println("Solution size " + result.size());
18 | result.stream()
19 | .map(points -> points.stream().map(this::replace).collect(Collectors.joining()))
20 | .forEach(System.out::println);
21 | Assert.assertEquals(92, result.size());
22 | }
23 |
24 | private String replace(Point p) {
25 | char[] chars = " 0 0 0 0 0 0 0 0\n".toCharArray();
26 | chars[p.y * 2 + 1] = 'x';
27 | return String.valueOf(chars);
28 | }
29 | }
--------------------------------------------------------------------------------
/src/test/java/recursivedp/_08_13_StackOfBoxesTest.java:
--------------------------------------------------------------------------------
1 | package recursivedp;
2 |
3 | import org.junit.Assert;
4 | import org.junit.Test;
5 | import recursivedp._08_13_StackOfBoxes.Box;
6 |
7 | import java.util.Arrays;
8 | import java.util.Collections;
9 |
10 | public class _08_13_StackOfBoxesTest {
11 |
12 | private final _08_13_StackOfBoxes s = new _08_13_StackOfBoxes();
13 |
14 |
15 | @Test
16 | public void with0Box() {
17 | Assert.assertEquals(0, s.createStack(Collections.emptyList()));
18 | }
19 |
20 | @Test
21 | public void with1Box() {
22 | Assert.assertEquals(1, s.createStack(Collections.singletonList(new Box(1, 1, 1))));
23 | }
24 |
25 | @Test
26 | public void with3Boxes() {
27 | Assert.assertEquals(5, s.createStack(Arrays.asList(
28 | new Box(2, 2, 2),
29 | new Box(3, 3, 3),
30 | new Box(3, 3, 4))));
31 | }
32 |
33 | @Test
34 | public void with4Boxes() {
35 | Assert.assertEquals(10, s.createStack(Arrays.asList(
36 | new Box(4, 4, 4),
37 | new Box(3, 3, 3),
38 | new Box(2, 2, 2),
39 | new Box(1, 1, 1))));
40 | }
41 | }
--------------------------------------------------------------------------------
/src/test/java/recursivedp/_08_14_BooleanEvaluationTest.java:
--------------------------------------------------------------------------------
1 | package recursivedp;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertEquals;
6 |
7 | public class _08_14_BooleanEvaluationTest {
8 |
9 | private _08_14_BooleanEvaluation s = new _08_14_BooleanEvaluation();
10 |
11 |
12 | @Test
13 | public void withEmptyExpression() {
14 | assertEquals(0, s.evaluate("", true));
15 | assertEquals(0, s.evaluate("", false));
16 | }
17 |
18 | @Test
19 | public void withOneValue() {
20 | assertEquals(0, s.evaluate("1", false));
21 | assertEquals(1, s.evaluate("1", true));
22 | assertEquals(0, s.evaluate("0", true));
23 | assertEquals(1, s.evaluate("0", false));
24 | }
25 |
26 |
27 | @Test
28 | public void withOneOperator() {
29 | assertEquals(1, s.evaluate("1&1", true));
30 | assertEquals(0, s.evaluate("1&0", true));
31 | assertEquals(0, s.evaluate("0&1", true));
32 | assertEquals(0, s.evaluate("0&0", true));
33 |
34 | assertEquals(0, s.evaluate("1&1", false));
35 | assertEquals(1, s.evaluate("1&0", false));
36 | assertEquals(1, s.evaluate("0&1", false));
37 | assertEquals(1, s.evaluate("0&0", false));
38 |
39 | assertEquals(1, s.evaluate("1|1", true));
40 | assertEquals(1, s.evaluate("1|0", true));
41 | assertEquals(1, s.evaluate("0|1", true));
42 | assertEquals(0, s.evaluate("0|0", true));
43 |
44 | assertEquals(0, s.evaluate("1|1", false));
45 | assertEquals(0, s.evaluate("1|0", false));
46 | assertEquals(0, s.evaluate("0|1", false));
47 | assertEquals(1, s.evaluate("0|0", false));
48 |
49 | assertEquals(0, s.evaluate("1^1", true));
50 | assertEquals(1, s.evaluate("0^1", true));
51 | assertEquals(1, s.evaluate("1^0", true));
52 | assertEquals(0, s.evaluate("0^0", true));
53 |
54 | assertEquals(1, s.evaluate("1^1", false));
55 | assertEquals(0, s.evaluate("0^1", false));
56 | assertEquals(0, s.evaluate("1^0", false));
57 | assertEquals(1, s.evaluate("0^0", false));
58 | }
59 |
60 | @Test
61 | public void withMultipleOperators() {
62 | assertEquals(2, s.evaluate("0|0|1", true));
63 | }
64 |
65 | @Test
66 | public void withMoreOperators() {
67 | assertEquals(2, s.evaluate("1^0|0|1", false));
68 | }
69 |
70 | @Test
71 | public void withMoreMoreOperators() {
72 | assertEquals(10, s.evaluate("0&0&0&1^1|0", true));
73 | }
74 | }
--------------------------------------------------------------------------------
/src/test/java/sortingsearching/_10_01_SortedMergeTest.java:
--------------------------------------------------------------------------------
1 | package sortingsearching;
2 |
3 | import org.junit.Assert;
4 | import org.junit.Test;
5 |
6 | import java.util.Arrays;
7 |
8 | public class _10_01_SortedMergeTest {
9 |
10 | private _10_01_SortedMerge s = new _10_01_SortedMerge();
11 |
12 | @Test
13 | public void withOneElementEach() {
14 | Assert.assertTrue(Arrays.equals(new int[]{1, 2}, s.merge(new int[]{2, 0}, new int[]{1})));
15 | }
16 |
17 | @Test
18 | public void withMultipleElementsEach() {
19 | Assert.assertTrue(Arrays.equals(new int[]{2, 3, 4, 5, 6}, s.merge(new int[]{2, 4, 6, 0, 0}, new int[]{3, 5})));
20 | }
21 | }
--------------------------------------------------------------------------------
/src/test/java/sortingsearching/_10_02_GroupAnagramsTest.java:
--------------------------------------------------------------------------------
1 | package sortingsearching;
2 |
3 | import org.junit.Assert;
4 | import org.junit.Test;
5 |
6 | import java.util.Arrays;
7 | import java.util.Collections;
8 |
9 | public class _10_02_GroupAnagramsTest {
10 |
11 | private _10_02_GroupAnagrams s = new _10_02_GroupAnagrams();
12 |
13 | @Test
14 | public void withEmpty() {
15 | Assert.assertEquals(Collections.emptyList(), s.groupAnagrams(Collections.emptyList()));
16 | }
17 |
18 | @Test
19 | public void withOneWord() {
20 | Assert.assertEquals(Collections.singletonList("hello"), s.groupAnagrams(Collections.singletonList("hello")));
21 | }
22 |
23 | @Test
24 | public void withThreeWords() {
25 | Assert.assertEquals(Arrays.asList("hello", "olelh", "world"), s.groupAnagrams(Arrays.asList("hello", "world", "olelh")));
26 | }
27 |
28 | @Test
29 | public void withFourWords() {
30 | Assert.assertEquals(Arrays.asList("hello", "olelh", "lrowd", "world"), s.groupAnagrams(Arrays.asList("hello", "lrowd", "olelh", "world")));
31 | }
32 | }
--------------------------------------------------------------------------------
/src/test/java/sortingsearching/_10_03_SearchInRotatedArrayTest.java:
--------------------------------------------------------------------------------
1 | package sortingsearching;
2 |
3 | import org.junit.Assert;
4 | import org.junit.Test;
5 |
6 | public class _10_03_SearchInRotatedArrayTest {
7 |
8 | private _10_03_SearchInRotatedArray s = new _10_03_SearchInRotatedArray();
9 |
10 | @Test
11 | public void withOneElement() {
12 | Assert.assertEquals(-1, s.find(new int[]{1}, 2));
13 | Assert.assertEquals(0, s.find(new int[]{1}, 1));
14 | }
15 |
16 | @Test
17 | public void withTwoElement() {
18 | Assert.assertEquals(1, s.find(new int[]{2, 1}, 1));
19 | Assert.assertEquals(0, s.find(new int[]{2, 1}, 2));
20 | Assert.assertEquals(-1, s.find(new int[]{2, 1}, 0));
21 | }
22 |
23 | @Test
24 | public void withMultipleElements() {
25 | Assert.assertEquals(8, s.find(new int[]{15, 16, 19, 20, 25, 1, 3, 4, 5, 7, 10, 14}, 5));
26 | }
27 |
28 | @Test
29 | public void withDuplicates() {
30 | Assert.assertEquals(8, s.find(new int[]{20, 20, 20, 20, 20, 20, 20, 20, 5, 7, 10, 14}, 5));
31 | int r = s.find(new int[]{20, 20, 20, 20, 20, 20, 20, 20, 5, 7, 10, 14}, 20);
32 | Assert.assertTrue(r >= 0 && r <= 7);
33 | }
34 | }
--------------------------------------------------------------------------------
/src/test/java/sortingsearching/_10_04_SortedSearchTest.java:
--------------------------------------------------------------------------------
1 | package sortingsearching;
2 |
3 | import org.junit.Assert;
4 | import org.junit.Test;
5 | import sortingsearching._10_04_SortedSearch.Listy;
6 |
7 | public class _10_04_SortedSearchTest {
8 |
9 | private _10_04_SortedSearch s = new _10_04_SortedSearch();
10 |
11 | @Test
12 | public void withEmptyListy() {
13 | Assert.assertEquals(-1, s.sortedSearch(Listy.of(), 1));
14 | }
15 |
16 | @Test
17 | public void withOneElem() {
18 | Assert.assertEquals(0, s.sortedSearch(Listy.of(1), 1));
19 | }
20 |
21 | @Test
22 | public void withMultipleElems() {
23 | Assert.assertEquals(3, s.sortedSearch(Listy.of(1, 3, 4, 5, 8, 10), 5));
24 | Assert.assertEquals(-1, s.sortedSearch(Listy.of(1, 3, 4, 5, 8, 10), 6));
25 | }
26 |
27 | @Test
28 | public void withDuplicates() {
29 | int actual = s.sortedSearch(Listy.of(1, 3, 4, 5, 5, 10), 5);
30 | Assert.assertTrue(actual == 3 || actual == 4);
31 | }
32 | }
--------------------------------------------------------------------------------
/src/test/java/sortingsearching/_10_05_SparseSearchTest.java:
--------------------------------------------------------------------------------
1 | package sortingsearching;
2 |
3 | import org.junit.Assert;
4 | import org.junit.Test;
5 |
6 | public class _10_05_SparseSearchTest {
7 |
8 | private final _10_05_SparseSearch sparseSearch = new _10_05_SparseSearch();
9 |
10 | @Test
11 | public void withEmptyString() {
12 | Assert.assertEquals(-1, sparseSearch.find(new String[]{"hello", "", "world"}, ""));
13 | }
14 |
15 | @Test
16 | public void withValidString() {
17 | Assert.assertEquals(8, sparseSearch.find(
18 | new String[]{"hello", "", "", "idea", "", "", "", "", "world", "", "", "", "", "", "xylo", "", ""},
19 | "world"));
20 |
21 | }
22 |
23 | @Test
24 | public void withManySparse() {
25 | Assert.assertEquals(0, sparseSearch.find(
26 | new String[]{"hello", "", "", "", "", "", "", "", "", "", "", "", "", ""},
27 | "hello"));
28 |
29 | }
30 | @Test
31 | public void withWordInTheEnd() {
32 | Assert.assertEquals(3, sparseSearch.find(
33 | new String[]{"", "", "", "hello"},
34 | "hello"));
35 |
36 | }
37 | }
--------------------------------------------------------------------------------
/src/test/java/stackqueue/_03_01_ThreeInOneTest.java:
--------------------------------------------------------------------------------
1 | package stackqueue;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertEquals;
6 |
7 | public class _03_01_ThreeInOneTest {
8 |
9 | @Test
10 | public void withStackSize1() {
11 | _03_01_ThreeInOne s = new _03_01_ThreeInOne(1);
12 | s.push(0, 0);
13 | s.push(1, 1);
14 | s.push(2, 2);
15 | assertEquals(0, s.pop(0));
16 | assertEquals(1, s.pop(1));
17 | assertEquals(2, s.pop(2));
18 | }
19 |
20 |
21 | @Test
22 | public void withStackSize2() {
23 | _03_01_ThreeInOne s = new _03_01_ThreeInOne(2);
24 | s.push(0, 6);
25 | s.push(1, 1);
26 | s.push(1, 2);
27 | s.push(2, 3);
28 | s.push(2, 4);
29 | s.push(2, 5);
30 | assertEquals(6, s.pop(0));
31 | assertEquals(2, s.pop(1));
32 | assertEquals(1, s.pop(1));
33 | assertEquals(5, s.pop(2));
34 | assertEquals(4, s.pop(2));
35 | assertEquals(3, s.pop(2));
36 | }
37 |
38 | @Test(expected = RuntimeException.class)
39 | public void withArrayLength3_Exceeded() {
40 | _03_01_ThreeInOne s = new _03_01_ThreeInOne(1);
41 | s.push(0, 1);
42 | s.push(0, 1);
43 | s.push(0, 1);
44 | s.push(0, 1);
45 | }
46 |
47 | @Test(expected = RuntimeException.class)
48 | public void withArrayLength3_StackNotExists() {
49 | _03_01_ThreeInOne s = new _03_01_ThreeInOne(3);
50 | s.push(3, 1);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/test/java/stackqueue/_03_02_MinStackTest.java:
--------------------------------------------------------------------------------
1 | package stackqueue;
2 |
3 | import org.junit.Test;
4 |
5 | import java.util.EmptyStackException;
6 |
7 | import static org.junit.Assert.assertEquals;
8 |
9 | public class _03_02_MinStackTest {
10 |
11 | private _03_02_MinStack s = new _03_02_MinStack();
12 |
13 | @Test
14 | public void withDecreasing() {
15 | s.push(3);
16 | s.push(2);
17 | s.push(1);
18 | assertEquals(1, s.min());
19 | assertEquals(1, s.pop());
20 | assertEquals(2, s.min());
21 | assertEquals(2, s.pop());
22 | assertEquals(3, s.min());
23 | assertEquals(3, s.pop());
24 | }
25 |
26 | @Test
27 | public void withInterleaving() {
28 | s.push(3);
29 | s.push(5);
30 | s.push(2);
31 | s.push(6);
32 | s.push(1);
33 |
34 | assertEquals(1, s.min());
35 | assertEquals(1, s.pop());
36 | assertEquals(2, s.min());
37 | assertEquals(6, s.pop());
38 | assertEquals(2, s.min());
39 | assertEquals(2, s.pop());
40 | assertEquals(3, s.min());
41 | assertEquals(5, s.pop());
42 | }
43 |
44 | @Test
45 | public void withInterleavingActions() {
46 | s.push(3);
47 | s.push(5);
48 | assertEquals(3, s.min());
49 | s.push(4);
50 | assertEquals(3, s.min());
51 | assertEquals(4, s.pop());
52 | assertEquals(5, s.pop());
53 | assertEquals(3, s.pop());
54 | }
55 |
56 | @Test(expected = EmptyStackException.class)
57 | public void withEmptyStack() {
58 | s.pop();
59 | }
60 | }
--------------------------------------------------------------------------------
/src/test/java/stackqueue/_03_03_StackOfPlatesTest.java:
--------------------------------------------------------------------------------
1 | package stackqueue;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertEquals;
6 |
7 | public class _03_03_StackOfPlatesTest {
8 |
9 | @Test
10 | public void withBigThreshold() {
11 | _03_03_StackOfPlates stack = new _03_03_StackOfPlates(100);
12 | stack.push(3);
13 | stack.push(4);
14 | stack.push(5);
15 | stack.push(6);
16 | assertEquals(6, stack.pop());
17 | assertEquals(5, stack.pop());
18 | assertEquals(4, stack.pop());
19 | assertEquals(3, stack.pop());
20 | }
21 |
22 | @Test
23 | public void withSmallThreshold() {
24 | _03_03_StackOfPlates stack = new _03_03_StackOfPlates(2);
25 | stack.push(3);
26 | stack.push(4);
27 | stack.push(5);
28 | stack.push(6);
29 | assertEquals(6, stack.pop());
30 | assertEquals(5, stack.pop());
31 | assertEquals(4, stack.pop());
32 | assertEquals(3, stack.pop());
33 | }
34 |
35 | @Test
36 | public void withSmallThreshold_PopAtIndex() {
37 | _03_03_StackOfPlates stack = new _03_03_StackOfPlates(2);
38 | stack.push(3);
39 | stack.push(4);
40 | stack.push(5);
41 | stack.push(6);
42 | stack.push(7);
43 | stack.push(8);
44 |
45 | assertEquals(6, stack.popAt(1));
46 | assertEquals(7, stack.popAt(1));
47 | assertEquals(8, stack.pop());
48 | assertEquals(4, stack.popAt(0));
49 | assertEquals(5, stack.pop());
50 | assertEquals(3, stack.pop());
51 |
52 | }
53 | }
--------------------------------------------------------------------------------
/src/test/java/stackqueue/_03_04_QueueViaStacksTest.java:
--------------------------------------------------------------------------------
1 | package stackqueue;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertEquals;
6 |
7 | public class _03_04_QueueViaStacksTest {
8 |
9 | private _03_04_QueueViaStacks s = new _03_04_QueueViaStacks();
10 |
11 | @Test
12 | public void withAllEnqueueAndAllDequeue() {
13 | s.enqueue(1);
14 | s.enqueue(2);
15 | s.enqueue(3);
16 | assertEquals(3, s.size());
17 | assertEquals(1, s.dequeue());
18 | assertEquals(2, s.size());
19 | assertEquals(2, s.dequeue());
20 | assertEquals(3, s.dequeue());
21 | }
22 |
23 | @Test
24 | public void withInterleavingEnqueueAndDequeue() {
25 | s.enqueue(1);
26 | assertEquals(1, s.dequeue());
27 | s.enqueue(2);
28 | s.enqueue(3);
29 | assertEquals(2, s.peek());
30 | assertEquals(2, s.dequeue());
31 | s.enqueue(4);
32 | assertEquals(3, s.dequeue());
33 | assertEquals(4, s.dequeue());
34 | }
35 |
36 | @Test(expected = RuntimeException.class)
37 | public void withEmptyQueue() {
38 | s.enqueue(1);
39 | s.dequeue();
40 | s.dequeue();
41 | }
42 | }
--------------------------------------------------------------------------------
/src/test/java/stackqueue/_03_05_SortStackTest.java:
--------------------------------------------------------------------------------
1 | package stackqueue;
2 |
3 | import org.junit.Test;
4 |
5 | import java.util.Stack;
6 |
7 | import static org.junit.Assert.assertEquals;
8 |
9 | public class _03_05_SortStackTest {
10 |
11 | private _03_05_SortStack s = new _03_05_SortStack();
12 |
13 | @Test
14 | public void withAlreadySorted() {
15 | Stack stack = new Stack<>();
16 | stack.push(3);
17 | stack.push(2);
18 | stack.push(1);
19 | Stack result = s.sort(stack);
20 | assertEquals(1, result.pop().intValue());
21 | assertEquals(2, result.pop().intValue());
22 | assertEquals(3, result.pop().intValue());
23 | }
24 |
25 | @Test
26 | public void withUnSorted() {
27 | Stack stack = new Stack<>();
28 | stack.push(2);
29 | stack.push(5);
30 | stack.push(3);
31 | stack.push(4);
32 | Stack result = s.sort(stack);
33 | assertEquals(2, result.pop().intValue());
34 | assertEquals(3, result.pop().intValue());
35 | assertEquals(4, result.pop().intValue());
36 | assertEquals(5, result.pop().intValue());
37 | }
38 | }
--------------------------------------------------------------------------------
/src/test/java/stackqueue/_03_06_AnimalShelterTest.java:
--------------------------------------------------------------------------------
1 | package stackqueue;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertEquals;
6 |
7 | public class _03_06_AnimalShelterTest {
8 |
9 | private _03_06_AnimalShelter s = new _03_06_AnimalShelter();
10 |
11 | @Test
12 | public void withOrdinaryQueue() {
13 | s.enqueueCat(5);
14 | s.enqueueDog(4);
15 | s.enqueueCat(6);
16 | s.enqueueCat(7);
17 |
18 | assertEquals(5, s.dequeueAny());
19 | assertEquals(4, s.dequeueAny());
20 | assertEquals(6, s.dequeueAny());
21 | assertEquals(7, s.dequeueAny());
22 | }
23 |
24 | @Test
25 | public void withCatDogOledest() {
26 | s.enqueueCat(5);
27 | s.enqueueCat(3);
28 | s.enqueueDog(6);
29 | s.enqueueDog(2);
30 | s.enqueueCat(1);
31 |
32 | assertEquals(6, s.dequeueDog());
33 | assertEquals(5, s.dequeueAny());
34 | assertEquals(3, s.dequeueAny());
35 | assertEquals(1, s.dequeueCat());
36 | assertEquals(2, s.dequeueDog());
37 | }
38 | }
--------------------------------------------------------------------------------
/src/test/java/treegraph/_04_01_RouteBetweenNodesTest.java:
--------------------------------------------------------------------------------
1 | package treegraph;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertFalse;
6 | import static org.junit.Assert.assertTrue;
7 |
8 | public class _04_01_RouteBetweenNodesTest {
9 |
10 | @Test
11 | public void withTwoVertex() {
12 | Digraph digraph = new Digraph(2);
13 | digraph.addEdge(0, 1);
14 | _04_01_RouteBetweenNodes routeBetweenNodes = new _04_01_RouteBetweenNodes(digraph);
15 | assertTrue(routeBetweenNodes.hasRoute(0, 1));
16 | assertFalse(routeBetweenNodes.hasRoute(1, 0));
17 | }
18 |
19 | @Test
20 | public void withMoreVertex() {
21 | Digraph digraph = new Digraph(5);
22 | digraph.addEdge(0, 1);
23 | digraph.addEdge(0, 2);
24 | digraph.addEdge(2, 3);
25 | digraph.addEdge(2, 4);
26 | _04_01_RouteBetweenNodes routeBetweenNodes = new _04_01_RouteBetweenNodes(digraph);
27 | assertTrue(routeBetweenNodes.hasRoute(0, 4));
28 | }
29 |
30 | @Test
31 | public void withCycle() {
32 | Digraph digraph = new Digraph(3);
33 | digraph.addEdge(0, 1);
34 | digraph.addEdge(1, 2);
35 | digraph.addEdge(2, 0);
36 | _04_01_RouteBetweenNodes routeBetweenNodes = new _04_01_RouteBetweenNodes(digraph);
37 | assertTrue(routeBetweenNodes.hasRoute(0, 1));
38 | assertTrue(routeBetweenNodes.hasRoute(0, 2));
39 | }
40 | }
--------------------------------------------------------------------------------
/src/test/java/treegraph/_04_02_MinimalTreeTest.java:
--------------------------------------------------------------------------------
1 | package treegraph;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertEquals;
6 | import static org.junit.Assert.assertNull;
7 |
8 | public class _04_02_MinimalTreeTest {
9 |
10 | private _04_02_MinimalTree s = new _04_02_MinimalTree();
11 |
12 | @Test
13 | public void withOneElement() {
14 | BinaryTreeNode binaryTreeNode = s.buildMinimalTree(new int[]{1});
15 | assertEquals(1, binaryTreeNode.val);
16 | assertNull(binaryTreeNode.left);
17 | assertNull(binaryTreeNode.right);
18 | }
19 |
20 | @Test
21 | public void withTwoElements() {
22 | BinaryTreeNode binaryTreeNode = s.buildMinimalTree(new int[]{1, 2});
23 | assertEquals(1, binaryTreeNode.val);
24 | assertEquals(2, binaryTreeNode.right.val);
25 | assertEquals(null, binaryTreeNode.left);
26 | }
27 |
28 | @Test
29 | public void withThreeElements() {
30 | BinaryTreeNode binaryTreeNode = s.buildMinimalTree(new int[]{1, 2, 3});
31 | assertEquals(2, binaryTreeNode.val);
32 | assertEquals(1, binaryTreeNode.left.val);
33 | assertEquals(3, binaryTreeNode.right.val);
34 | }
35 |
36 | @Test
37 | public void withFourElements() {
38 | BinaryTreeNode binaryTreeNode = s.buildMinimalTree(new int[]{1, 2, 3, 4});
39 | assertEquals(2, binaryTreeNode.val);
40 | assertEquals(1, binaryTreeNode.left.val);
41 | assertEquals(3, binaryTreeNode.right.val);
42 | assertEquals(4, binaryTreeNode.right.right.val);
43 | }
44 |
45 | }
--------------------------------------------------------------------------------
/src/test/java/treegraph/_04_03_ListOfDepthsTest.java:
--------------------------------------------------------------------------------
1 | package treegraph;
2 |
3 | import org.junit.Test;
4 |
5 | import java.util.*;
6 |
7 | import static org.junit.Assert.assertEquals;
8 |
9 | public class _04_03_ListOfDepthsTest {
10 |
11 | private _04_03_ListOfDepths s = new _04_03_ListOfDepths();
12 |
13 | @Test
14 | public void withOneElement() {
15 | List> linkedLists = s.create(new BinaryTreeNode(1));
16 | List> results = new ArrayList<>();
17 | results.add(new LinkedList<>(Collections.singletonList(1)));
18 | assertEquals(results, linkedLists);
19 | }
20 |
21 | @Test
22 | public void withTwoElements() {
23 | BinaryTreeNode node = new BinaryTreeNode(1);
24 | node.left = new BinaryTreeNode(2);
25 | List> linkedLists = s.create(node);
26 | List> results = new ArrayList<>();
27 | results.add(new LinkedList<>(Collections.singletonList(1)));
28 | results.add(new LinkedList<>(Collections.singletonList(2)));
29 | assertEquals(results, linkedLists);
30 | }
31 |
32 | @Test
33 | public void withThreeElements() {
34 | BinaryTreeNode node = new BinaryTreeNode(1);
35 | node.left = new BinaryTreeNode(2);
36 | node.right = new BinaryTreeNode(3);
37 | List> linkedLists = s.create(node);
38 | List> results = new ArrayList<>();
39 | results.add(new LinkedList<>(Collections.singletonList(1)));
40 | results.add(new LinkedList<>(Arrays.asList(2, 3)));
41 | assertEquals(results, linkedLists);
42 | }
43 | }
--------------------------------------------------------------------------------
/src/test/java/treegraph/_04_04_CheckBalancedTest.java:
--------------------------------------------------------------------------------
1 | package treegraph;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertFalse;
6 | import static org.junit.Assert.assertTrue;
7 |
8 | public class _04_04_CheckBalancedTest {
9 |
10 | private _04_04_CheckBalanced s = new _04_04_CheckBalanced();
11 |
12 | @Test
13 | public void withOneNode() {
14 | assertTrue(s.isBalanced(new BinaryTreeNode(1)));
15 | }
16 |
17 | @Test
18 | public void withTwoNodes() {
19 | BinaryTreeNode root = new BinaryTreeNode(1);
20 | root.left = new BinaryTreeNode(2);
21 | assertTrue(s.isBalanced(root));
22 | }
23 |
24 | @Test
25 | public void withThreeNodes() {
26 | BinaryTreeNode root = new BinaryTreeNode(1);
27 | root.left = new BinaryTreeNode(2);
28 | root.right = new BinaryTreeNode(3);
29 | assertTrue(s.isBalanced(root));
30 | }
31 |
32 | @Test
33 | public void withFourNodes_Unbalanced() {
34 | BinaryTreeNode root = new BinaryTreeNode(1);
35 | root.left = new BinaryTreeNode(2);
36 | root.left.left = new BinaryTreeNode(3);
37 | assertFalse(s.isBalanced(root));
38 | }
39 |
40 | @Test
41 | public void withSameHeight_Unbalanced() {
42 | BinaryTreeNode root = new BinaryTreeNode(1);
43 | root.left = new BinaryTreeNode(2);
44 | root.left.left = new BinaryTreeNode(3);
45 | root.left.right = new BinaryTreeNode(7);
46 | root.left.left.left = new BinaryTreeNode(6);
47 | root.left.left.left.left = new BinaryTreeNode(8);
48 | root.right = new BinaryTreeNode(4);
49 | root.right.right = new BinaryTreeNode(5);
50 | root.right.right.right = new BinaryTreeNode(9);
51 | assertFalse(s.isBalanced(root));
52 | }
53 | }
--------------------------------------------------------------------------------
/src/test/java/treegraph/_04_05_ValidateBSTTest.java:
--------------------------------------------------------------------------------
1 | package treegraph;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertFalse;
6 | import static org.junit.Assert.assertTrue;
7 |
8 | public class _04_05_ValidateBSTTest {
9 |
10 | private _04_05_ValidateBST s = new _04_05_ValidateBST();
11 |
12 | @Test
13 | public void withOneNode() {
14 | assertTrue(s.isBST(new BinaryTreeNode(1)));
15 | }
16 |
17 | @Test
18 | public void withTwoNodes() {
19 | BinaryTreeNode node = new BinaryTreeNode(2);
20 | node.left = new BinaryTreeNode(1);
21 | assertTrue(s.isBST(node));
22 | }
23 |
24 | @Test
25 | public void withThreeNodes() {
26 | BinaryTreeNode node = new BinaryTreeNode(2);
27 | node.left = new BinaryTreeNode(1);
28 | node.right = new BinaryTreeNode(3);
29 | assertTrue(s.isBST(node));
30 | }
31 |
32 | @Test
33 | public void withTreeNodes_NotBalanced() {
34 | BinaryTreeNode node = new BinaryTreeNode(2);
35 | node.left = new BinaryTreeNode(1);
36 | node.right = new BinaryTreeNode(1);
37 | assertFalse(s.isBST(node));
38 | }
39 |
40 | }
--------------------------------------------------------------------------------
/src/test/java/treegraph/_04_06_SuccessorTest.java:
--------------------------------------------------------------------------------
1 | package treegraph;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertEquals;
6 | import static org.junit.Assert.assertNull;
7 |
8 | public class _04_06_SuccessorTest {
9 |
10 | private _04_06_Successor s = new _04_06_Successor();
11 |
12 | @Test
13 | public void withOneNode() {
14 | assertNull(s.findInOrderSuccessor(new ParentAwareBinaryTreeNode(1)));
15 | }
16 |
17 | @Test
18 | public void withTwoNodes() {
19 | ParentAwareBinaryTreeNode root = new ParentAwareBinaryTreeNode(2);
20 | root.addLeft(1);
21 | assertEquals(2, s.findInOrderSuccessor(root.left).val);
22 | }
23 |
24 | @Test
25 | public void withFourNodes() {
26 | ParentAwareBinaryTreeNode root = new ParentAwareBinaryTreeNode(2);
27 | root.addLeft(1);
28 | root.addRight(4).addRight(6).addLeft(5);
29 | assertEquals(4, s.findInOrderSuccessor(root).val);
30 | }
31 |
32 | @Test
33 | public void withTargetNodeARightNode() {
34 | ParentAwareBinaryTreeNode root = new ParentAwareBinaryTreeNode(6);
35 | root.addLeft(4).addRight(5);
36 | assertEquals(6, s.findInOrderSuccessor(root.left.right).val);
37 | }
38 |
39 | @Test
40 | public void withTargetNodeARightNode_AndWithChild() {
41 | ParentAwareBinaryTreeNode root = new ParentAwareBinaryTreeNode(8);
42 | root.addLeft(4).addRight(6).addRight(7);
43 | assertEquals(7, s.findInOrderSuccessor(root.left.right).val);
44 | }
45 |
46 | @Test
47 | public void withTargetNodeADeepRightNode() {
48 | ParentAwareBinaryTreeNode root = new ParentAwareBinaryTreeNode(8);
49 | root.addLeft(1).addRight(2).addRight(3).addRight(4);
50 | assertEquals(8, s.findInOrderSuccessor(root.left.right.right.right).val);
51 | }
52 | }
--------------------------------------------------------------------------------
/src/test/java/treegraph/_04_07_BuildOrderTest.java:
--------------------------------------------------------------------------------
1 | package treegraph;
2 |
3 | import org.junit.Test;
4 |
5 | import java.util.Arrays;
6 | import java.util.Collections;
7 |
8 | import static org.junit.Assert.assertEquals;
9 | import static org.junit.Assert.assertNull;
10 |
11 | public class _04_07_BuildOrderTest {
12 |
13 | private _04_07_BuildOrder s = new _04_07_BuildOrder();
14 |
15 | @Test
16 | public void withOneProject() {
17 | Digraph digraph = new Digraph(1);
18 | assertEquals(Collections.singletonList(0), s.findBuildOrder(digraph));
19 | }
20 |
21 | @Test
22 | public void withTwoProjects() {
23 | Digraph digraph = new Digraph(2);
24 | digraph.addEdge(1, 0);
25 | assertEquals(Arrays.asList(0, 1), s.findBuildOrder(digraph));
26 | }
27 |
28 | @Test
29 | public void withMoreProjects() {
30 | Digraph digraph = new Digraph(4);
31 | digraph.addEdge(3, 1);
32 | digraph.addEdge(2, 1);
33 | digraph.addEdge(1, 0);
34 | assertEquals(Arrays.asList(0, 1, 2, 3), s.findBuildOrder(digraph));
35 | }
36 |
37 | @Test
38 | public void withTwoGroups() {
39 | Digraph digraph = new Digraph(4);
40 | digraph.addEdge(1, 0);
41 | digraph.addEdge(3, 2);
42 | assertEquals(Arrays.asList(0, 1, 2, 3), s.findBuildOrder(digraph));
43 | }
44 |
45 | @Test
46 | public void withCycle() {
47 | Digraph digraph = new Digraph(3);
48 | digraph.addEdge(0, 1);
49 | digraph.addEdge(1, 2);
50 | digraph.addEdge(2, 0);
51 | assertNull(s.findBuildOrder(digraph));
52 | }
53 | }
--------------------------------------------------------------------------------
/src/test/java/treegraph/_04_08_FindCommonAncestorTest.java:
--------------------------------------------------------------------------------
1 | package treegraph;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertEquals;
6 |
7 | public class _04_08_FindCommonAncestorTest {
8 |
9 | private _04_08_FindCommonAncestor s = new _04_08_FindCommonAncestor();
10 |
11 | @Test
12 | public void withOneNode() {
13 | ParentAwareBinaryTreeNode node = new ParentAwareBinaryTreeNode(1);
14 | assertEquals(node, s.findCommonAncestor(node, node));
15 | }
16 |
17 | @Test
18 | public void withTwoNodes() {
19 | ParentAwareBinaryTreeNode node = new ParentAwareBinaryTreeNode(1);
20 | node.addLeft(2);
21 | assertEquals(node, s.findCommonAncestor(node, node.left));
22 | }
23 |
24 | @Test
25 | public void withThreeNodes() {
26 | ParentAwareBinaryTreeNode node = new ParentAwareBinaryTreeNode(1);
27 | node.addLeft(2);
28 | node.addRight(3);
29 | assertEquals(node, s.findCommonAncestor(node.left, node.right));
30 | }
31 |
32 | @Test
33 | public void withMoreNodes() {
34 | ParentAwareBinaryTreeNode node = new ParentAwareBinaryTreeNode(1);
35 | node.addLeft(2);
36 | ParentAwareBinaryTreeNode ancestor = node.addRight(3);
37 | ParentAwareBinaryTreeNode a = ancestor.addLeft(4).addRight(5);
38 | ParentAwareBinaryTreeNode b = ancestor.addRight(6).addRight(7).addRight(8);
39 | assertEquals(ancestor, s.findCommonAncestor(a, b));
40 | }
41 | }
--------------------------------------------------------------------------------
/src/test/java/treegraph/_04_09_BSTSequencesTest.java:
--------------------------------------------------------------------------------
1 | package treegraph;
2 |
3 | import org.junit.Test;
4 |
5 | import java.util.Arrays;
6 | import java.util.Collections;
7 |
8 | import static org.junit.Assert.assertEquals;
9 |
10 | public class _04_09_BSTSequencesTest {
11 |
12 | private _04_09_BSTSequences s = new _04_09_BSTSequences();
13 |
14 | @Test
15 | public void withOneNode() {
16 | assertEquals(Collections.singletonList(Collections.singletonList(1)), s.sequences(new BinaryTreeNode(1)));
17 | }
18 |
19 | @Test
20 | public void withTwoNodes() {
21 | BinaryTreeNode root = new BinaryTreeNode(1);
22 | root.right = new BinaryTreeNode(2);
23 | assertEquals(Collections.singletonList(Arrays.asList(1, 2)), s.sequences(root));
24 | }
25 |
26 | @Test
27 | public void withThreeNodes() {
28 | BinaryTreeNode root = new BinaryTreeNode(2);
29 | root.left = new BinaryTreeNode(1);
30 | root.right = new BinaryTreeNode(3);
31 | assertEquals(Arrays.asList(Arrays.asList(2, 1, 3), Arrays.asList(2, 3, 1)), s.sequences(root));
32 | }
33 |
34 | @Test
35 | public void withMoreNodes() {
36 | BinaryTreeNode root = new BinaryTreeNode(5);
37 | root.left = new BinaryTreeNode(3);
38 | root.left.left = new BinaryTreeNode(2);
39 | root.left.right = new BinaryTreeNode(4);
40 | root.right = new BinaryTreeNode(7);
41 | assertEquals(
42 | Arrays.asList(
43 | Arrays.asList(5, 3, 2, 4, 7),
44 | Arrays.asList(5, 3, 2, 7, 4),
45 | Arrays.asList(5, 3, 7, 2, 4),
46 | Arrays.asList(5, 7, 3, 2, 4),
47 | Arrays.asList(5, 3, 4, 2, 7),
48 | Arrays.asList(5, 3, 4, 7, 2),
49 | Arrays.asList(5, 3, 7, 4, 2),
50 | Arrays.asList(5, 7, 3, 4, 2)
51 | ),
52 | s.sequences(root));
53 | }
54 | }
--------------------------------------------------------------------------------
/src/test/java/treegraph/_04_10_CheckSubTreeTest.java:
--------------------------------------------------------------------------------
1 | package treegraph;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertFalse;
6 | import static org.junit.Assert.assertTrue;
7 |
8 | public class _04_10_CheckSubTreeTest {
9 |
10 | private _04_10_CheckSubTree s = new _04_10_CheckSubTree();
11 |
12 | @Test
13 | public void withOneNode() {
14 | BinaryTreeNode a = new BinaryTreeNode(1);
15 | BinaryTreeNode b = new BinaryTreeNode(1);
16 | assertTrue(s.isSubTree(a, b));
17 | }
18 |
19 | @Test
20 | public void withTwoNodes() {
21 | BinaryTreeNode a = new BinaryTreeNode(1);
22 | a.left = new BinaryTreeNode(2);
23 | BinaryTreeNode b = new BinaryTreeNode(2);
24 | assertTrue(s.isSubTree(a, b));
25 | }
26 |
27 | @Test
28 | public void withMoreNodes() {
29 | BinaryTreeNode a = new BinaryTreeNode(1);
30 | a.right = new BinaryTreeNode(2);
31 | a.right.right = new BinaryTreeNode(3);
32 | a.right.right.left = new BinaryTreeNode(4);
33 | a.right.right.right = new BinaryTreeNode(5);
34 |
35 | BinaryTreeNode b = new BinaryTreeNode(3);
36 | b.left = new BinaryTreeNode(4);
37 | b.right = new BinaryTreeNode(5);
38 |
39 | assertTrue(s.isSubTree(a, b));
40 | }
41 |
42 | @Test
43 | public void withDiffTree() {
44 | BinaryTreeNode a = new BinaryTreeNode(1);
45 | a.left = new BinaryTreeNode(2);
46 | a.right = new BinaryTreeNode(3);
47 | BinaryTreeNode b = new BinaryTreeNode(4);
48 | assertFalse(s.isSubTree(a, b));
49 | }
50 |
51 | @Test
52 | public void withSamePreOrder() {
53 | BinaryTreeNode a = new BinaryTreeNode(1);
54 | a.left = new BinaryTreeNode(2);
55 | a.right = new BinaryTreeNode(3);
56 |
57 | BinaryTreeNode b = new BinaryTreeNode(1);
58 | b.right = new BinaryTreeNode(2);
59 | b.left = new BinaryTreeNode(3);
60 |
61 | assertFalse(s.isSubTree(a, b));
62 | }
63 | }
--------------------------------------------------------------------------------
/src/test/java/treegraph/_04_11_RandomNodeTest.java:
--------------------------------------------------------------------------------
1 | package treegraph;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | public class _04_11_RandomNodeTest {
8 |
9 | @Test
10 | public void withSimpleCase() {
11 | _04_11_RandomNode.Tree tree = new _04_11_RandomNode.Tree();
12 | tree.insert(5);
13 | tree.insert(2);
14 | tree.insert(1);
15 | tree.insert(3);
16 | tree.insert(6);
17 | assertEquals(3, tree.find(3).getVal());
18 | assertNull(tree.find(4));
19 | assertNotNull(tree.getRandomNode());
20 | }
21 | }
--------------------------------------------------------------------------------
/src/test/java/treegraph/_04_12_PathsWithSumTest.java:
--------------------------------------------------------------------------------
1 | package treegraph;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertEquals;
6 |
7 | public class _04_12_PathsWithSumTest {
8 |
9 | private _04_12_PathsWithSum s = new _04_12_PathsWithSum();
10 |
11 | @Test
12 | public void withOneNode() {
13 | BinaryTreeNode root = new BinaryTreeNode(1);
14 | assertEquals(0, s.countPathWithSum(root, 2));
15 | assertEquals(1, s.countPathWithSum(root, 1));
16 | }
17 |
18 | @Test
19 | public void withThreeNodes() {
20 | BinaryTreeNode root = new BinaryTreeNode(1);
21 | root.left = new BinaryTreeNode(1);
22 | root.right = new BinaryTreeNode(2);
23 | assertEquals(2, s.countPathWithSum(root, 1));
24 | assertEquals(2, s.countPathWithSum(root, 2));
25 | assertEquals(1, s.countPathWithSum(root, 3));
26 | assertEquals(0, s.countPathWithSum(root, 4));
27 | }
28 |
29 | @Test
30 | public void withMoreDepths() {
31 | BinaryTreeNode root = new BinaryTreeNode(10);
32 | root.left = new BinaryTreeNode(5);
33 | root.left.left = new BinaryTreeNode(3);
34 | root.left.left.left = new BinaryTreeNode(3);
35 | root.left.left.right = new BinaryTreeNode(-2);
36 | root.left.right = new BinaryTreeNode(1);
37 | root.left.right.right = new BinaryTreeNode(2);
38 |
39 | root.right = new BinaryTreeNode(-3);
40 | root.right.right = new BinaryTreeNode(-11);
41 |
42 | assertEquals(2, s.countPathWithSum(root, 8));
43 |
44 | }
45 | }
--------------------------------------------------------------------------------