Skip to content

Commit c5059b3

Browse files
committed
Updated 4 solutions
1 parent 6e8d606 commit c5059b3

File tree

7 files changed

+47
-73
lines changed

7 files changed

+47
-73
lines changed
Lines changed: 19 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,35 @@
11
package _4_12_Paths_with_Sum;
22

3-
import java.util.ArrayList;
43
import common.TreeNode;
4+
import java.util.*;
55

6-
// The Big Trick
7-
//
8-
// Instead of checking if a node starts a path that sums to "value", we check if it ENDS a path summing to "value".
96

107
public class PathWithSums {
11-
public static void findSum(TreeNode node, int value) {
12-
findSum(node, value, new ArrayList<TreeNode>());
8+
public static int findSum(TreeNode node, int targetSum) {
9+
Map<Integer, Integer> map = new HashMap<>();
10+
map.put(0, 1);
11+
return findSum(node, targetSum, 0, map);
1312
}
1413

15-
/* Recursive function */
16-
private static void findSum(TreeNode node, int value, ArrayList<TreeNode> path) {
14+
private static int findSum(TreeNode node, int targetSum, int runningSum, Map<Integer, Integer> map) {
1715
if (node == null) {
18-
return;
16+
return 0;
1917
}
20-
path.add(node);
21-
checkSums(path, value);
22-
findSum(node.left, value, path);
23-
findSum(node.right, value, path);
24-
path.remove(node); // We have 1 "remove" for each 1 "add"
25-
}
2618

27-
/* We sum paths in REVERSE order to see if they equal 'value' */
28-
private static void checkSums(ArrayList<TreeNode> path, int value) {
29-
int sum = 0;
30-
for (int i = path.size() - 1; i >= 0; i--) { // We must loop backwards
31-
sum += path.get(i).data;
32-
if (sum == value) {
33-
printPath(path, i, path.size() - 1);
34-
}
35-
}
36-
}
19+
runningSum += node.data;
20+
int totalPaths = map.getOrDefault(runningSum - targetSum, 0);
3721

38-
private static void printPath(ArrayList<TreeNode> path, int start, int end) {
39-
System.out.println();
40-
for (int i = start; i <= end; i++) {
41-
System.out.print(path.get(i).data + " ");
22+
map.merge(runningSum, 1, Integer::sum);
23+
totalPaths += findSum(node.left, targetSum, runningSum, map);
24+
totalPaths += findSum(node.right, targetSum, runningSum, map);
25+
map.merge(runningSum, -1, Integer::sum);
26+
if (map.get(runningSum) == 0) { // Remove when 0 to reduce space usage
27+
map.remove(runningSum);
4228
}
29+
30+
return totalPaths;
4331
}
4432
}
4533

46-
// Time/Space complexities: Assuming BALANCED binary tree
47-
// Time complexity: O(n log(n)) since we touch all "n" nodes, and findSum is O(log n)) in AVERAGE case.
48-
// findSum worst case is O((log n)^2) since it may call print every single time,
49-
// making overall time complexity worst case O(n (log n)^2)
50-
// Space complexity: O(log n) since that's the max size of a path, and also the max amount of recursive calls on stack.
34+
// Time Complexity: O(n)
35+
// Space Complexity: O(log n) on balanced tree. O(n) otherwise.

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ public class Tester {
77
public static void main(String[] args) {
88
System.out.print("*** Test 4.12: Paths with Sum\n");
99
TreeNode tree = TreeFunctions.createBST();
10-
PathWithSums.findSum(tree, 6);
10+
int result = PathWithSums.findSum(tree, 6);
11+
System.out.println(result);
1112
}
1213
}

Chp. 08 - Recursion and Dynamic Programming/_8_02_Robot_in_a_Grid/Point.java

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

3-
/* Used in 9.2 */
43
public class Point {
54
public int x;
65
public int y;
@@ -14,11 +13,9 @@ public class Point {
1413
// http://javarevisited.blogspot.com/2011/02/how-to-write-equals-method-in-java.html
1514
// http://javarevisited.blogspot.com/2011/10/override-hashcode-in-java-example.html
1615

17-
/* Here for 9.2 to work with hashing Points */
1816
@Override
19-
public boolean equals(Object other) { // must take an "Object" as a
20-
// parameter, not a "Point", so that
21-
// it overrides the .equals method
17+
public boolean equals(Object other) { // must take an "Object" as a parameter, not a
18+
// "Point", so that it overrides the .equals method
2219
if (other == this) {
2320
return true;
2421
} else if (other == null || !(other instanceof Point)) {

Chp. 08 - Recursion and Dynamic Programming/_8_02_Robot_in_a_Grid/RobotInAGrid.java

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package _8_02_Robot_in_a_Grid;
22

3-
import java.util.ArrayList;
4-
import java.util.HashMap;
3+
import java.util.*;
54

65
public class RobotInAGrid {
76

@@ -80,38 +79,36 @@ private static boolean isFree(boolean[][] maze, int row, int col) {
8079
/* Follow-up (from website): Find ALL Paths */
8180
/********************************************/
8281
// similar to 8-Queens Problem.
83-
// I search from end to start (makes code simpler to write)
8482
// no point in caching results since we have to try all paths
85-
public static ArrayList<ArrayList<Point>> allPaths(boolean[][] maze, int row, int col) {
83+
public static List<List<Point>> allPaths(boolean[][] maze, int row, int col) {
8684
if (maze == null || row >= maze.length || col >= maze[0].length) {
8785
return null;
8886
}
89-
ArrayList<Point> path = new ArrayList<Point>();
90-
ArrayList<ArrayList<Point>> solutionPaths = new ArrayList<ArrayList<Point>>();
91-
getAllPaths(maze, row, col, path, solutionPaths);
87+
List<List<Point>> solutionPaths = new ArrayList<>();
88+
getAllPaths(maze, 0, 0, solutionPaths, new ArrayList<>());
9289
return solutionPaths;
9390
}
9491

95-
public static void getAllPaths(boolean[][] maze, int row, int col, ArrayList<Point> path, ArrayList<ArrayList<Point>> solutionPaths) {
92+
public static void getAllPaths(boolean[][] maze, int row, int col, List<List<Point>> solutionPaths, List<Point> path) {
9693
if (!isFree(maze, row, col)) {
9794
return;
9895
}
9996
Point p = new Point(col, row);
10097
path.add(p);
101-
if (row == 0 && col == 0) {
98+
if (row == maze.length - 1 && col == maze[0].length - 1) {
10299
// Shallow copy would give us the correct solution too but each ArrayList<Point> in solutionPaths would
103100
// contain Points that are references to other Points in a different ArrayList<Point> in solutionsPaths
104101
deepCopyPathIntoSolutions(path, solutionPaths);
105102
// we do not add a "return" here so that the code will eventually get to "path.remove(p)"
106103
}
107-
getAllPaths(maze, row, col - 1, path, solutionPaths);
108-
getAllPaths(maze, row - 1, col, path, solutionPaths);
104+
getAllPaths(maze, row, col + 1, solutionPaths, path);
105+
getAllPaths(maze, row + 1, col, solutionPaths, path);
109106
path.remove(p); // notice there is exactly 1 .remove() since we had exactly 1 .add()
110107
}
111108

112-
private static void deepCopyPathIntoSolutions(ArrayList<Point> path, ArrayList<ArrayList<Point>> solutionPaths) {
113-
ArrayList<Point> solutionPath = new ArrayList<>();
114-
for (int i = path.size() - 1; i >= 0; i--) { // I reverse the order of the path here since we stored it backwards
109+
private static void deepCopyPathIntoSolutions(List<Point> path, List<List<Point>> solutionPaths) {
110+
List<Point> solutionPath = new ArrayList<>();
111+
for (int i = 0; i < path.size(); i++) {
115112
Point point = path.get(i);
116113
solutionPath.add(new Point(point.x, point.y));
117114
}

Chp. 08 - Recursion and Dynamic Programming/_8_02_Robot_in_a_Grid/Tester.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package _8_02_Robot_in_a_Grid;
22

3-
import java.util.ArrayList;
3+
import java.util.*;
44

55
public class Tester {
66
public static void main(String[] args) {
@@ -28,7 +28,7 @@ private static void test_FindOnePath() {
2828
private static void test_FindAllPaths() {
2929
System.out.println("\n\n\n*** Test Follow-up: Find All Paths\n");
3030
boolean[][] maze = createMaze(3, 3);
31-
ArrayList<ArrayList<Point>> solutionPaths = RobotInAGrid.allPaths(maze, 2, 2);
31+
List<List<Point>> solutionPaths = RobotInAGrid.allPaths(maze, 2, 2);
3232
printAllPaths(solutionPaths);
3333
}
3434

@@ -42,9 +42,9 @@ private static boolean[][] createMaze(int rows, int cols) {
4242
return maze;
4343
}
4444

45-
private static void printAllPaths(ArrayList<ArrayList<Point>> solutionPaths) {
45+
private static void printAllPaths(List<List<Point>> solutionPaths) {
4646
if (solutionPaths != null) {
47-
for (ArrayList<Point> path : solutionPaths) {
47+
for (List<Point> path : solutionPaths) {
4848
System.out.println(path);
4949
}
5050
}

Chp. 16 - More Problems (Moderate)/_16_08_English_Int/EnglishInt.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public static String numToString(int num) {
2323
int bigsIndex = 0;
2424
StringBuffer sb = new StringBuffer();
2525

26-
// We create the string from right to left, inserting in the front. This makes code clean and scalability easier
26+
// Create the string from right to left, inserting in the front.
2727
while (num > 0) {
2828
if (num % 1000 != 0) {
2929
sb.insert(0, numToString100(num % 1000) + bigs[bigsIndex] + " ");

Chp. 17 - More Problems (Hard)/_17_20_Continuous_Median/ContinuousMedian.java

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,25 @@
44
import java.util.PriorityQueue;
55

66
//- We use 2 Heaps to keep track of median
7+
// - maxHeap contains all SMALL elements
8+
// - minHeap contains all LARGE elements
79
//- We make sure that 1 of the following conditions is always true:
810
// 1) maxHeap.size() == minHeap.size()
911
// 2) maxHeap.size() - 1 = minHeap.size()
1012

1113
public class ContinuousMedian {
12-
private static PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder()); // maxHeap contains all SMALL elements
13-
private static PriorityQueue<Integer> minHeap = new PriorityQueue<>(); // minHeap contains all LARGE elements
14+
private static PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder());
15+
private static PriorityQueue<Integer> minHeap = new PriorityQueue<>();
1416

1517
public static void addNum(int n) {
1618
if (maxHeap.isEmpty()) {
1719
maxHeap.add(n);
1820
} else if (maxHeap.size() == minHeap.size()) {
19-
if (n < minHeap.peek()) {
20-
maxHeap.add(n);
21-
} else {
22-
minHeap.add(n);
23-
maxHeap.add(minHeap.remove());
24-
}
21+
minHeap.add(n);
22+
maxHeap.add(minHeap.remove());
2523
} else if (maxHeap.size() > minHeap.size()) {
26-
if (n > maxHeap.peek()) {
27-
minHeap.add(n);
28-
} else {
29-
maxHeap.add(n);
30-
minHeap.add(maxHeap.remove());
31-
}
24+
maxHeap.add(n);
25+
minHeap.add(maxHeap.remove());
3226
}
3327
// maxHeap will never be smaller size than minHeap
3428
}

0 commit comments

Comments
 (0)