1
1
package chapter08RecursionAndDynamicProgramming ;
2
2
3
+ import java .util .ArrayList ;
4
+ import java .util .HashSet ;
5
+ import java .util .List ;
6
+ import java .util .Set ;
7
+
3
8
/**
4
9
*
5
- * Problem:
10
+ * Problem: Imagine a robot sitting on the upper left corner of grid with r rows
11
+ * and c columns. The robot can only move in two directions, right and down, but
12
+ * certain cells are "off limits" such that the robot cannot step on them.
13
+ * Design an algorithm to find a path for the robot from the top left to the
14
+ * bottom right.
6
15
*
7
16
*/
8
17
public class RobotInAGrid {
9
18
19
+ /**
20
+ * Method 1: Duplicate work
21
+ *
22
+ * Time Complexity: O(2(r + c)). each path has r + c steps and there are two
23
+ * choices we can make at each step.
24
+ */
25
+
26
+ public List <Point > getPath1 (boolean [][] maze ) {
27
+ if (maze == null || maze .length == 0 ) {
28
+ return null ;
29
+ }
30
+ List <Point > res = new ArrayList <>();
31
+ if (getPath1 (maze , maze .length - 1 , maze [0 ].length - 1 , res )) {
32
+ return res ;
33
+ }
34
+ return null ;
35
+ }
36
+
37
+ private boolean getPath1 (boolean [][] maze , int row , int col , List <Point > path ) {
38
+ // out of bounds or not available
39
+ if (!maze [row ][col ] || col < 0 || row < 0 ) {
40
+ return false ;
41
+ }
42
+ boolean isAtOrigin = (row == 0 ) && (col == 0 );
43
+ if (getPath1 (maze , row , col - 1 , path ) || getPath1 (maze , row - 1 , col , path ) || isAtOrigin ) {
44
+ Point p = new Point (row , col );
45
+ path .add (p );
46
+ return true ;
47
+ }
48
+ return false ;
49
+ }
50
+
51
+ /**
52
+ * Method 2:
53
+ *
54
+ * Time Complexity: O(rc), we hit each cell just once.
55
+ */
56
+ public List <Point > getPath2 (boolean [][] maze ) {
57
+ if (maze == null || maze .length == 0 ) {
58
+ return null ;
59
+ }
60
+ List <Point > res = new ArrayList <>();
61
+ Set <Point > failedPoints = new HashSet <>();
62
+ if (getPath2 (maze , maze .length - 1 , maze [0 ].length - 1 , res , failedPoints )) {
63
+ return res ;
64
+ }
65
+ return null ;
66
+ }
67
+
68
+ private boolean getPath2 (boolean [][] maze , int row , int col , List <Point > path , Set <Point > failedPoints ) {
69
+ // out of bounds or not available
70
+ if (!maze [row ][col ] || col < 0 || row < 0 ) {
71
+ return false ;
72
+ }
73
+ Point p = new Point (row , col );
74
+ if (failedPoints .contains (p )) {
75
+ return false ;
76
+ }
77
+ boolean isAtOrigin = (row == 0 ) && (col == 0 );
78
+ if (getPath2 (maze , row , col - 1 , path , failedPoints ) || getPath2 (maze , row - 1 , col , path , failedPoints )
79
+ || isAtOrigin ) {
80
+ path .add (p );
81
+ return true ;
82
+ }
83
+ return false ;
84
+ }
85
+
10
86
}
87
+
88
+ class Point {
89
+ int row ;
90
+ int col ;
91
+
92
+ public Point (int row , int col ) {
93
+ this .row = row ;
94
+ this .col = col ;
95
+ }
96
+
97
+ @ Override
98
+ public String toString () {
99
+ return "(" + row + "," + col + ")" ;
100
+ }
101
+
102
+ @ Override
103
+ public int hashCode () {
104
+ return this .toString ().hashCode ();
105
+ }
106
+
107
+ @ Override
108
+ public boolean equals (Object o ) {
109
+ if ((o instanceof Point ) && ((Point ) o ).row == this .row && ((Point ) o ).col == this .col ) {
110
+ return true ;
111
+ } else {
112
+ return false ;
113
+ }
114
+ }
115
+ }
0 commit comments