I just can’t get the hang of recursion, especially with complicated examples. I would really appreciate it if someone would take some time to explain it. I literally have 4 pieces of paper all filled with me tracing this function, but I have no idea how to put it together.
public static String shortestPath(int x, int y, int tX, int tY,boolean blocked[][]) {
if(x>blocked.length-1 || y>blocked[0].length-1 || x<0 || y<0 )
return null;
if(blocked[x][y]==true)
return null;
if(x==tX && y==tY)
return "";
String paths[]=new String[4];
blocked[x][y]=true; //this just means this coordinate is blocked, so dont use it
paths[0]=shortestPath(x, y+1, tX, tY, blocked);
paths[1]=shortestPath(x, y-1, tX, tY, blocked);
paths[2]=shortestPath(x+1, y, tX, tY, blocked);
paths[3]=shortestPath(x-1, y, tX, tY, blocked);
blocked[x][y] = false;
int result=findShortestString(paths, 0, 3);
//findShortestString just takes an array of strings,
//with 0 being the lo index and 3 being the hi,
//and returns the index that contains the string with the shortest length.
//5
if(paths[result]==null)
return null;
else{
if(result==0)
return 'N' + paths[result];
if(result==1)
return 'S' + paths[result];
if(result==2)
return 'E' + paths[result];
if(result==3)
return 'W' + paths[result];}
return paths[result];
So what this code does is, given an x and y parameter, it tells you the shortest combination of moves you would have to make (NSWE for north, south, west, east) in order to reach the tX and tY parameters. The code works perfectly, but I have no idea how.
When I try to trace what paths[0] computes, it always comes out to null, because y will always keep incrementing until it goes out of bounds, in which it returns null. This is the same case for paths[1] [2] and [3], they all return to null, don’t they? So then how the heck is this function working?
First try it with a trivially small example – a 1×1 grid with no blocked cells. As expected, there are no moves to be made.
x == tXandy == tYso you return empty string. Good so far.Now look at a 2×2 grid where you are in the NW corner and the destination is NE.
When you try to go east and set
paths[0]it invokesshortestPath, blocking off your current cell and setting your new location to the one below you. Now you haveIn that invocation, it’s going to try to go N, W, S and E. Ignore for simplicity that going east happens before west, so we can finish up the other 3 directions right away – they all invoke again
shortestPathon an invalid location (2 out of bounds, 1 you’ve been to) and returnnullimmediately. You are left going east with a new grid and location like this:Again, 3 of the directions return
null. Only north will give you the end result you want. When you try to go there, you once again invokeshortestPathwhich immediately returns empty string because the board now looks like this:Now we get to wrap up the call stack:
paths[1]was empty string and the other 3 werenull,resultis 1 (I assume that’s how your string function works). So you return"N"to the previous call.paths[0] == null,paths[1] == null,paths[3] == nullbut criticallypaths[2]is"N". Thereforeresultwill be 2, and you will return"EN"to the earlier call.Since now you are returning to the very first invocation of
shortestPath, that wraps up the first choice we made – going south from the start position. But we also had 1 more choice – go east. So you follow that tree out and it is simply"".Then comes the final step, where you see which string is smaller and get that
""is of course smaller than"EN". Soresultis 2, and therefore you prefix the string with"E", and"E"is your final answer.Now use that to figure out the larger examples. It helps to draw a decision tree and the state of the board at each node. And as you get to the leaves, draw arrows going back up to the parent node representing return values. That will help immensely.