Path with Maximum Gold

Updated on 10 July, 2025
Path with Maximum Gold header image

Problem Statement

In a specified grid representing a gold mine, where each cell contains a numeric value indicating the amount of gold or zero (representing an empty cell), the objective is to calculate the maximum amount of gold collectible. This maneuver involves navigating from one cell to another adjacent cell (either left, right, up, or down) while adhering to specific rules such as collecting all the gold in the cell once you land on it, not revisiting a cell, and avoiding empty cells entirely. The process starts and ends at any cell that contains gold, and the goal is to maximize the total collected gold from selected traversal paths in the grid.

Examples

Example 1

Input:

grid = [[0,6,0],[5,8,7],[0,9,0]]

Output:

24

Explanation:

[[0,6,0],
[5,8,7],
[0,9,0]]
Path to get the maximum gold, 9 -> 8 -> 7.

Example 2

Input:

grid = [[1,0,7],[2,0,6],[3,4,5],[0,3,0],[9,0,20]]

Output:

28

Explanation:

[[1,0,7],
[2,0,6],
[3,4,5],
[0,3,0],
[9,0,20]]
Path to get the maximum gold, 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7.

Constraints

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 15
  • 0 <= grid[i][j] <= 100
  • There are at most 25 cells containing gold.

Approach and Intuition

The core of solving this problem revolves around navigating the grid strategically to maximize gold collection. Here’s the thought process and direction of how one might approach this problem:

  1. Start by identifying all potential starting points. These are the grid cells that contain gold (value > 0).

  2. Utilize a depth-first search (DFS) strategy to explore possible moves from each starting cell. The DFS will help in simulating the traversal through each possible path, adhering to the constraints of movement and cell revisits.

  3. For each cell with gold, attempt moves in all four cardinal directions: up, down, left, and right. Check boundaries to ensure the movements are within grid limits and the target cells are not revisited and are not empty.

  4. Maintain a running count of collected gold for each path and a global maximum that updates if a particular path results in a higher gold count than previously recorded paths.

  5. Implement backtracking within the DFS to allow exploration of alternate paths after visiting a cell. Reset visitation status and collected gold count appropriately after moving back to a previous cell.

  6. The depth of the search and the optimizations like starting from cells with the highest amount of gold first or pruning paths that descend into areas with lesser gold could help in achieving more efficient solutions considering computational constraints.

In essence, the solution relies on combing through all feasible paths from each cell containing gold and strategically depth-first navigating while backtracking to explore different configurations. This structured exploration is crucial in ensuring all potential maxima are duly considered. Additionally, the constraints help bound the problem, making a detailed search feasible even for relatively larger grid sizes permitted by the problem (up to 15x15 grids).

Solutions

  • C++
cpp
class Solution {
public:
    int findMaxGold(vector<vector<int>>& map) {
        int height = map.size();
        int width = map[0].size();
            
        int sumGold = 0;
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                sumGold += map[i][j];
            }
        }
            
        int finalMaxGold = 0;
    
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                if (map[i][j] != 0) {
                    finalMaxGold = max(finalMaxGold, goldSearchDfs(map, height, width, i, j));
                    if (finalMaxGold == sumGold)
                        return sumGold;
                }
            }
        }
        return finalMaxGold;
    }
    
private:
    const vector<int> MOVE_DIR = {0, 1, 0, -1, 0};
    
    int goldSearchDfs(vector<vector<int>>& map,
                      int height, int width, int x, int y) {
        queue<tuple<int, int, int, bitset<1024>>> q;
        bitset<1024> marked;
        int richestPath = 0;
        marked[x * width + y] = 1;
        q.push({x, y, map[x][y], marked});
    
        while (!q.empty()) {
            auto [currentX, currentY, gatheredGold, visitState] = q.front();
            q.pop();
            richestPath = max(richestPath, gatheredGold);
    
            for (int i = 0; i < 4; i++) {
                int nextX = currentX + MOVE_DIR[i];
                int nextY = currentY + MOVE_DIR[i + 1];
    
                if (nextX >= 0 && nextX < height && nextY >= 0 && nextY < width &&
                        map[nextX][nextY] != 0 &&
                        !visitState[nextX * width + nextY]) {
                    visitState[nextX * width + nextY] = 1;
                    q.push({nextX, nextY, gatheredGold + map[nextX][nextY], 
                            visitState});
                    visitState[nextX * width + nextY] = 0;
                }
            }
        }
        return richestPath;
    }
};

Explore the solution for the Path with Maximum Gold in C++. This solution entails using a deep first search (DFS) strategy to traverse all possible paths in a grid that represents a gold map where each cell contains some amount of gold.

The primary function, findMaxGold, first initializes the total grid size and calculates the total sum of gold. It then iteratively checks each cell in the grid; if the cell contains gold, it calls the goldSearchDfs function, which initiates the depth-first search.

  • goldSearchDfs employs a queue to process each possible move from the current cell that contains gold.
  • Directions for movements are defined in MOVE_DIR.
  • Each cell's position and the cumulative gold gathered up to that point are tracked.
  • A bitset named marked tracks visited cells to avoid cycles and backtracking to already visited cells.

This approach ensures that all paths from each starting gold-containing cell are considered, and the maximum amount of gold collected in any path is determined. The function returns this maximum value.

This method efficiently identifies the path with the highest yield of gold by exploring every potential path starting from any cell containing gold, harnessing a breadth-first search for comprehensive coverage without revisiting or backtracking unnecessarily.

  • Java
java
class Solution {
    private final int[] MOVES = new int[] { 0, 1, 0, -1, 0 };
        
    public int findMaxGold(int[][] matrix) {
        int maxRows = matrix.length;
        int maxCols = matrix[0].length;
            
        int entireGold = 0;
        // Calculate total gold in matrix
        for (int[] row : matrix) {
            for (int gold : row) {
                entireGold += gold;
            }
        }
            
        // Attempt to find the maximum gold via DFS for each cell
        int highestGold = 0;
        for (int r = 0; r < maxRows; r++) {
            for (int c = 0; c < maxCols; c++) {
                if (matrix[r][c] != 0) {
                    highestGold = Math.max(highestGold, depthSearch(matrix, maxRows, maxCols, r, c));
                    // Early exit if possible
                    if (highestGold == entireGold) {
                        return entireGold;
                    }
                }
            }
        }
        return highestGold;
    }
    
    // Depth First Search - Backtracking
    private int depthSearch(int[][] matrix, int maxRows, int maxCols, int r, int c) {
        Queue<Pair<int[], Set<String>>> paths = new ArrayDeque<>();
        Set<String> seen = new HashSet<>();
        int collectedGold = 0;
        seen.add(r + "," + c);
        paths.add(new Pair<>(new int[] { r, c, matrix[r][c] }, seen));
    
        while (!paths.isEmpty()) {
            Pair<int[], Set<String>> currentPath = paths.poll();
            int currentR = currentPath.getKey()[0];
            int currentC = currentPath.getKey()[1];
            int currentGold = currentPath.getKey()[2];
            Set<String> currentSeen = currentPath.getValue();
            collectedGold = Math.max(collectedGold, currentGold);
    
            for (int move = 0; move < 4; move++) {
                int newRow = currentR + MOVES[move];
                int newCol = currentC + MOVES[move + 1];
    
                if (newRow >= 0 && newRow < maxRows && newCol >= 0 && newCol < maxCols &&
                    matrix[newRow][newCol] != 0 &&
                    !currentSeen.contains(newRow + "," + newCol)) {
                        
                    currentSeen.add(newRow + "," + newCol);
                    Set<String> newVisited = new HashSet<>(currentSeen);
                    paths.add(new Pair<>(new int[] { newRow, newCol, 
                                        currentGold + matrix[newRow][newCol]}, newVisited));
                    currentSeen.remove(newRow + "," + newCol);
                }
            }
        }
        return collectedGold;
    }
}

The Java solution provided aims to solve the problem of finding the path in a matrix that yields the maximum amount of gold by using depth-first search (DFS) and backtracking methodology.

Here's a concise guide through the implementation:

  • Initialize directional moves to help navigate through the matrix.
  • Compute the total quantity of gold present in the matrix. This will be used to determine an optimal stopping point for the search if this maximum is reached during DFS.
  • Initialize the highestGold variable to store the maximum gold found starting from any cell.
  • Iteratively kickstart DFS from each cell that contains gold. If the cell contains gold (not zero), invoke the depthSearch function.
  • The depthSearch function is designed to navigate through the matrix:
    • Utilize a queue to manage states in the DFS, where each state contains the current position, the amount of gold collected from the start to that position, and a set of visited positions to avoid cycles.
    • Explore possible moves in four directions from the current cell. If a move leads to a valid and unvisited cell containing gold, calculate the new amount of gold collected, and enqueue this new state for further exploration.
    • Constantly update the collectedGold with the maximum gold found during these explorations.
  • The termination of the DFS occurs either when all possibilities are exhaustively searched or the maximum gold recorded equals the maximal theoretical collection (entireGold), allowing an early termination.

This depth-first search approach combined with backtracking ensures that all potential paths are considered, thereby guaranteeing that the maximum gold collecting path is found effectively, even in cases where multiple routes are possible with varying amounts of gold deposits.

  • Python
python
class MaxGoldFinder:
    def maximumGold(self, mine: List[List[int]]) -> int:
        MOVE = [0, 1, 0, -1, 0]
        max_rows = len(mine)
        max_cols = len(mine[0])
            
        def backtrack_gold(r: int, c: int) -> int:
            stack = deque()
            seen = set()
            peak_gold = 0
            seen.add((r, c))
            stack.append((r, c, mine[r][c], seen))
            while stack:
                current_r, current_c, gold_collected, visited = stack.pop()
                peak_gold = max(peak_gold, gold_collected)
    
                # Explore all 4 adjacent directions
                for i in range(4):
                    adj_r = current_r + MOVE[i]
                    adj_c = current_c + MOVE[i + 1]
    
                    if 0 <= adj_r < max_rows and 0 <= adj_c < max_cols and \
                            mine[adj_r][adj_c] != 0 and \
                            (adj_r, adj_c) not in visited:
                        visited.add((adj_r, adj_c))
                        stack.append((adj_r, adj_c, 
                                      gold_collected + mine[adj_r][adj_c], 
                                      visited.copy()))
                        visited.remove((adj_r, adj_c))
            return peak_gold
    
        # Total gold potentially available
        entire_gold = sum(sum(row) for row in mine)
            
        # Evaluate maximum gold obtainable starting from each cell
        ultimate_gold = 0
        for r in range(max_rows):
            for c in range(max_cols):
                if mine[r][c] != 0:
                    ultimate_gold = max(ultimate_gold, backtrack_gold(r, c))
                    if ultimate_gold == entire_gold:
                        return entire_gold
        return ultimate_gold

The provided Python program defines a class MaxGoldFinder with a method maximumGold that calculates the maximum amount of gold that can be collected from a grid, starting from any cell containing gold and moving to adjacent cells (up, down, left, right) that also contain gold.

Here is the solution breakdown:

  • Initialization:

    • The grid, represented as a list of lists mine, is used to store the gold values.
    • The dimensions of the grid, max_rows and max_cols, are determined by the size of mine.
  • Nested Function - backtrack_gold:

    • Takes row index (r) and column index (c) as input and initializes the stack and seen set for remembering visited positions.
    • Main loop pops from stack to get the current position and gold collected so far. It then tries to move to all four adjacent cells (using the MOVE array for directional movement).
    • If a move is valid (staying within grid boundaries, moving to a cell with gold, and not revisiting a cell), the function updates the stack with new position and increased gold total.
    • Each move is checked against the current maximum, and updates peak_gold if a higher value is found.
  • Main Logic in maximumGold:

    • The entire_gold variable captures the total amount of gold theoretically available on the grid (summing up all cells).
    • Iterates over every cell in mine. If the cell has gold, it calls backtrack_gold to determine the maximum gold that can be collected starting from that cell.
    • Store the highest result in ultimate_gold.
    • Optimization: If ever ultimate_gold matches entire_gold, the search can terminate early as the optimal path has been found.

This enables the function to efficiently find the path through the grid that collects the maximum amount of gold by leveraging depth-first search (DFS) implemented with a stack, and selective recursion for exploring all potential paths. The approach accounts for the possibility of revisiting cells to ensure that calculations aren't skewed by changing prior paths, making use of set operations to manage visited nodes effectively.

Comments

No comments yet.