You can modify dfs
to keep track of the path and have it return a pair of Integer (the sum) and a String representing the path:
import java.util.Map;
import java.util.Map.Entry;
class Main {
public static void main(String[] args) {
char[][] matrix = {
{'.','X','.','.','X','.','.'},
{'2','.','.','.','2','.','.'},
{'.','.','X','.','1','.','.'},
{'2','.','.','.','.','.','X'}
};
Entry<Integer, String> result = dfs(matrix,0,0,new int[matrix.length][matrix[0].length],"");
System.out.println(result.getKey() +" "+ result.getValue());
}
//Entry is used as a container for an int-string pair
public static Entry<Integer, String> dfs(char[][] matrix, int i, int j, int[][] cache, String path) {
cache[i][j]=0;//clear previous sum
if (matrix[i][j] != 'X' && matrix[i][j] != 'x' && matrix[i][j] != '.') {
cache[i][j] += Character.getNumericValue(matrix[i][j]);
}
int iDown = i + 1;
int jRight = j + 1;
Entry<Integer,String> resultDown = null;
Entry<Integer,String> resultRight = null;
if (iDown < matrix.length && matrix[iDown][j] != 'X' && matrix[iDown][j] != 'x') {
resultDown = dfs(matrix, iDown, j, cache, path+"D");
if(resultDown.getKey() <= 0) { //no values found
resultDown = null;
}
}
if (jRight < matrix[0].length && matrix[i][jRight] != 'X' && matrix[i][jRight] != 'x') {
resultRight = dfs(matrix, i, jRight, cache, path+"R");
if(resultRight.getKey() <= 0) { //no values found
resultRight = null;
}
}
//no values found moving right or down
if(resultDown == null && resultRight == null) return Map.entry(cache[i][j], path);
String newPath = path;
if(resultDown != null && resultRight != null){ //values found in both directions
if(resultDown.getKey() > resultRight.getKey()) {
cache[i][j]+= resultDown.getKey();
newPath = resultDown.getValue();
}else {
cache[i][j] += resultRight.getKey();
newPath = resultRight.getValue();
}
}else /*values found only in one direction*/if(resultDown != null ) {
cache[i][j] += resultDown.getKey();
newPath = resultDown.getValue();
}else{
cache[i][j] += resultRight.getKey();
newPath = resultRight.getValue();
}
return Map.entry(cache[i][j] , newPath);
}
}
A better and more Object Oriented approach is to define a Node
object, for example:
class Node {
private final char value;
private String direction;
private Node child = null;
private int sum = 0;
public Node(char value) {
this.value = value;
}
public String getDirection() {
return direction;
}
public void setDirection(String direction) {
this.direction = direction;
}
public Node getChild() {
return child;
}
public void setChild(Node parent) {
child = parent;
}
public char getValue() {
return value;
}
public int getSum() {
return sum;
}
public void addToSum(int add) {
sum += add;
}
}
and run dfs on a graph of Node
s (for example Node[][]
).