Skip to content

Commit 802ec4e

Browse files
committed
updated 6 solutions
1 parent 0eed2b1 commit 802ec4e

File tree

6 files changed

+82
-90
lines changed

6 files changed

+82
-90
lines changed

Chp. 04 - Trees and Graphs/_4_02_Minimal_Tree/MinimalTree.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
public class MinimalTree {
66
public static TreeNode createBST(int[] sortedArray) {
7+
if (sortedArray == null) {
8+
return null;
9+
}
710
return createBST(sortedArray, 0, sortedArray.length - 1);
811
}
912

@@ -18,3 +21,6 @@ private static TreeNode createBST(int[] sortedArray, int startIndex, int endInde
1821
return root;
1922
}
2023
}
24+
25+
// Time Complexity: O(n)
26+
// Space Complexity: O(n) since we're creating a Binary Search Tree
Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,31 @@
11
package _4_03_List_of_Depths;
22

3-
import java.util.ArrayList;
4-
import java.util.LinkedList;
3+
import java.util.*;
54
import common.TreeNode;
65

76
public class ListOfDepths {
8-
public static ArrayList<LinkedList<TreeNode>> createLists(TreeNode root) {
9-
ArrayList<LinkedList<TreeNode>> lists = new ArrayList<>();
10-
createListsHelper(root, lists, 0);
11-
return lists;
12-
}
13-
14-
private static void createListsHelper(TreeNode node, ArrayList<LinkedList<TreeNode>> lists, int currLevel) {
15-
if (node == null) {
16-
return;
7+
public static List<List<Integer>> levelOrder(TreeNode root) {
8+
List<List<Integer>> lists = new ArrayList<>();
9+
if (root == null) {
10+
return lists;
1711
}
18-
19-
/* Tricky. May need a new list for a new level */
20-
if (lists.size() == currLevel) { // levels are visited in order, so this should work.
21-
lists.add(new LinkedList<TreeNode>());
12+
ArrayDeque<TreeNode> deque = new ArrayDeque<>(); // use deque as a queue
13+
deque.add(root);
14+
while (!deque.isEmpty()) {
15+
int numNodesInLevel = deque.size();
16+
List<Integer> level = new ArrayList<>(numNodesInLevel);
17+
for (int i = 0; i < numNodesInLevel; i++) {
18+
TreeNode n = deque.remove();
19+
level.add(n.data);
20+
if (n.left != null) {
21+
deque.add(n.left);
22+
}
23+
if (n.right != null) {
24+
deque.add(n.right);
25+
}
26+
}
27+
lists.add(level);
2228
}
23-
24-
/* Add this Node */
25-
LinkedList<TreeNode> list = lists.get(currLevel); // get the appropriate list to add the node to.
26-
list.add(new TreeNode(node.data)); // DEEP COPY - don't forget!
27-
28-
/* Recursively add this nodes subtrees */
29-
createListsHelper(node.left, lists, currLevel + 1);
30-
createListsHelper(node.right, lists, currLevel + 1);
29+
return lists;
3130
}
3231
}
33-
34-
// Tricky Implementation Details:
35-
// 1) Knowing to return an "ArrayList<LinkedList<Node>>".
36-
// 2) Knowing that, to alter the "ArrayList<LinkedList<Node>>", we should pass it as a parameter so it can be altered.
37-
// 3) Know to also pass the "level" down the tree.
38-
// 4) Remembering to create new LinkedLists in our ArrayList when necessary.
39-
// 5) Making a DEEP COPY whenever we add Nodes to the list.

Chp. 04 - Trees and Graphs/_4_03_List_of_Depths/Tester.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
11
package _4_03_List_of_Depths;
22

3-
import java.util.ArrayList;
4-
import java.util.LinkedList;
3+
import java.util.*;
54
import common.TreeNode;
65
import common.TreeFunctions;
76

87
public class Tester {
98
public static void main(String[] args) {
109
System.out.println("*** Test 4.3: List of Depths");
1110
TreeNode tree = TreeFunctions.createBST();
12-
ArrayList<LinkedList<TreeNode>> lists = ListOfDepths.createLists(tree);
11+
List<List<Integer>> lists = ListOfDepths.levelOrder(tree);
1312
for (int i = 0; i < lists.size(); i++) {
14-
LinkedList<TreeNode> list = lists.get(i);
13+
List<Integer> list = lists.get(i);
1514
System.out.format("\nLevel %d: ", i);
16-
for (TreeNode node : list) {
17-
System.out.print(node);
15+
for (Integer num : list) {
16+
System.out.print(num);
1817
}
1918
}
2019
}

Chp. 04 - Trees and Graphs/_4_04_Check_Balanced/CheckBalanced.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
public class CheckBalanced {
88
public static boolean isBalanced(TreeNode root) {
9-
return (isBalancedHelper(root) == -1) ? false : true;
9+
return isBalancedHelper(root) != -1;
1010
}
1111

1212
/* Returns -1 if unbalanced, otherwise returns height of tree from given node */
@@ -28,9 +28,10 @@ private static int isBalancedHelper(TreeNode root) {
2828
if (Math.abs(leftHeight - rightHeight) > 1) {
2929
return -1; // imbalance between the 2 subtrees
3030
}
31+
3132
return 1 + Math.max(leftHeight, rightHeight);
3233
}
3334
}
3435

3536
// Time Complexity: O(n)
36-
// Space Complexity: O(n)
37+
// Space Complexity: O(log n) if balanced tree. O(n) otherwise.
Lines changed: 27 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,39 @@
11
package _10_03_Search_in_Rotated_Array;
22

33
// - Trick: Endpoints of array give us valuable information. We apply a modified binary search to this problem.
4-
//
5-
// - Pitfall: We want to break up the cases by comparing midValue to leftValue. DO NOT break it up by comparing midValue to the
6-
// value we are searching for like in binary search
7-
//
8-
// - Array can only have 1 inflection point, therefore it is either to the left or right of midIndex. That means 1/2 of the array
9-
// is ordered normally (in increasing order) and the other half has the inflection point.
4+
// - Although binary search compares the "middle value" to the "target value", we will break up
5+
// the cases differently. We will compare middle value `A[mid]` to the start value `A[lo]`
6+
// - Array can only have 1 inflection point, therefore it is either to the left or right of `mid`.
7+
// That means 1/2 of the array is ordered normally (in increasing order) and the other half has the inflection point.
108

119
public class SearchInRotatedArray {
12-
public static Integer search(int[] rotatedArray, int x) {
13-
return search(rotatedArray, x, 0, rotatedArray.length - 1);
14-
}
15-
16-
private static Integer search(int[] rotatedArray, int x, int start, int end) {
17-
if (start > end) {
18-
return null;
19-
}
20-
int midIndex = (start + end) / 2;
21-
int midValue = rotatedArray[midIndex];
22-
23-
int leftValue = rotatedArray[start];
24-
int rightValue = rotatedArray[end];
25-
26-
if (midValue == x) {
27-
return midIndex;
28-
} else if (leftValue < midValue) { // in this case, left CANNOT have inflection point, thus is ordered correctly
29-
if (leftValue <= x && x < midValue) {
30-
return search(rotatedArray, x, start, midIndex - 1);
31-
} else {
32-
return search(rotatedArray, x, midIndex + 1, end);
33-
}
34-
} else if (leftValue > midValue) { // in this case, left MUST have inflection point, and thus is not ordered correctly
35-
if (midValue < x && x <= rightValue) {
36-
return search(rotatedArray, x, midIndex + 1, end);
37-
} else {
38-
return search(rotatedArray, x, start, midIndex - 1);
10+
public static Integer search(int[] A, int target) {
11+
int lo = 0;
12+
int hi = A.length - 1;
13+
while (lo <= hi) {
14+
int mid = (lo + hi) / 2;
15+
if (A[mid] == target) {
16+
return mid;
3917
}
40-
} else { // leftValue == midValue
41-
if (midValue == rightValue) { // leftValue == midValue == rightValue, so we must search both halves of array since either half could have inflection point
42-
Integer result = search(rotatedArray, x, start, midIndex - 1);
43-
if (result == null) {
44-
result = search(rotatedArray, x, midIndex + 1, end);
18+
if (A[lo] < A[mid]) { // in this case, left side CANNOT have inflection point, and is increasing.
19+
if (A[lo] <= target && target < A[mid]) {
20+
hi = mid - 1;
21+
} else {
22+
lo = mid + 1;
23+
}
24+
} else if (A[lo] > A[mid]) {
25+
if (A[mid] < target && target <= A[hi]) {
26+
lo = mid + 1;
27+
} else {
28+
hi = mid - 1;
4529
}
46-
return result;
47-
} else { // in this case, inflection point is on right side of array
48-
return search(rotatedArray, x, midIndex + 1, end);
30+
} else { // This iteration of while loop did not divide problem in half.
31+
lo++; // Removes just 1 invalid match.
4932
}
5033
}
34+
return null;
5135
}
5236
}
5337

54-
// Time Complexity: O(log n) average case, but O(n) worst case if there are many duplicates.
38+
// Time Complexity: O(n) due to possible duplicates in array
39+
// Space Complexity: O(1)

Chp. 17 - More Problems (Hard)/_17_10_Majority_Element/MajorityElement.java

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,35 @@
22

33
import java.util.Arrays;
44

5+
// Let's assume (for now), that the array has a valid majority element
6+
//
7+
// Loop through the array. At each index `i`, we treat the array as 2 pieces:
8+
// - prefix as `[0, i)`
9+
// - suffix as `[i, end]`
10+
// Main idea: If we don't have a majority element in the prefix, then the suffix must have a majority element,
11+
// and this majority element will also be the majority element for the entire array.
12+
513
public class MajorityElement {
614
public static Integer majorityElement(int[] array) {
15+
if (array == null) {
16+
return null;
17+
}
718
Integer majority = getCandidate(array);
819
return isMajorityValid(array, majority) ? majority : null;
920
}
1021

1122
private static Integer getCandidate(int[] array) {
12-
int majority = 0;
1323
int count = 0;
14-
for (int n : array) {
15-
if (count == 0) {
16-
majority = n;
17-
}
18-
if (majority == n) {
19-
count++;
20-
} else {
21-
count--;
24+
Integer candidate = null;
25+
26+
for (int num : array) {
27+
if (count == 0) { // no majority element in prefix
28+
candidate = num; // selects new candidate majority element
2229
}
30+
count += (num == candidate) ? 1 : -1;
2331
}
24-
return majority;
32+
33+
return candidate;
2534
}
2635

2736
private static boolean isMajorityValid(int[] array, int majority) {

0 commit comments

Comments
 (0)