Skip to main content

Cherry Pickup II - LeetCode Daily Challenge

Aakash Verma

Problem Statement

You are given a rows x cols matrix grid representing a field of cherries where grid[i][j] represents the number of cherries that you can collect from the (i, j) cell.

You have two robots that can collect cherries for you:

  • Robot #1 is located at the top-left corner (0, 0), and
  • Robot #2 is located at the top-right corner (0, cols - 1).

Return the maximum number of cherries collection using both robots by following the rules below:

  • From a cell (i, j), robots can move to cell (i + 1, j - 1)(i + 1, j), or (i + 1, j + 1).
  • When any robot passes through a cell, It picks up all cherries, and the cell becomes an empty cell.
  • When both robots stay in the same cell, only one takes the cherries.
  • Both robots cannot move outside of the grid at any moment.
  • Both robots should reach the bottom row in grid.

Example 1

Input: grid = [[3,1,1],[2,5,1],[1,5,5],[2,1,1]]
Output: 24
Explanation: Path of robot #1 and #2 are described in color green and blue respectively.
Cherries taken by Robot #1, (3 + 2 + 5 + 2) = 12.
Cherries taken by Robot #2, (1 + 5 + 5 + 1) = 12.
Total of cherries: 12 + 12 = 24.

Example 2

Input: grid = [[1,0,0,0,0,0,1],[2,0,0,0,0,3,0],[2,0,9,0,0,0,0],[0,3,0,5,4,0,0],[1,0,2,3,0,0,6]]
Output: 28
Explanation: Path of robot #1 and #2 are described in color green and blue respectively.
Cherries taken by Robot #1, (1 + 9 + 5 + 2) = 17.
Cherries taken by Robot #2, (1 + 3 + 4 + 3) = 11.
Total of cherries: 17 + 11 = 28.

Try here before watching the video.

Video Solution

Java Code

class Solution {

    int[] dir = new int[]{-1, 0, 1};

    private int solve(int row, int col1, int col2, int rows, int cols, int[][] grid, int[][][] dp) {
        if(row == rows) {
            return 0;
        }

        if(col1 < 0 || col2 < 0 || col1 >= cols || col2 >= cols) {
            return Integer.MIN_VALUE;
        }

        if(dp[row][col1][col2] != -1) {
            return dp[row][col1][col2];
        }

        int maxCherries = 0;

        for(int i = 0; i < 3; i++) {
            for(int j = 0; j < 3; j++) {
                maxCherries = Math.max(maxCherries, solve(row + 1, col1 + dir[i], col2 + dir[j], rows, cols, grid, dp));
            }
        }

        if(col1 == col2) {
            maxCherries += grid[row][col1];
        } else {
            maxCherries += (grid[row][col1] + grid[row][col2]);
        }

        return dp[row][col1][col2] = maxCherries;
    }
    public int cherryPickup(int[][] grid) {
        int rows = grid.length;
        int cols = grid[0].length;
        int[][][] dp = new int[rows][cols][cols];
        for(int i = 0; i < rows; i++) {
            for(int j = 0; j < cols; j++) {
                Arrays.fill(dp[i][j], -1);
            }
        }
        return solve(0, 0, cols - 1, rows, cols, grid, dp);
    }
}

C++ Code

class Solution {
public:
    
    int dir[3] = {-1, 0, 1};

    int solve(int row, int col1, int col2, int rows, int cols, vector<vector<int>>& grid, vector<vector<vector<int>>>& dp) {
        if (row == rows) {
            return 0;
        }

        if (col1 < 0 || col2 < 0 || col1 >= cols || col2 >= cols) {
            return INT_MIN;
        }

        if (dp[row][col1][col2] != -1) {
            return dp[row][col1][col2];
        }

        int maxCherries = 0;

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                maxCherries = max(maxCherries, solve(row + 1, col1 + dir[i], col2 + dir[j], rows, cols, grid, dp));
            }
        }

        if (col1 == col2) {
            maxCherries += grid[row][col1];
        } else {
            maxCherries += (grid[row][col1] + grid[row][col2]);
        }

        return dp[row][col1][col2] = maxCherries;
    }

    int cherryPickup(vector<vector<int>>& grid) {
        int rows = grid.size();
        int cols = grid[0].size();
        vector<vector<vector<int>>> dp(rows, vector<vector<int>>(cols, vector<int>(cols, -1)));

        return solve(0, 0, cols - 1, rows, cols, grid, dp);
    }
};

Python Code

class Solution:

    dir = [-1, 0, 1]
    
    def solve(self, row, col1, col2, rows, cols, grid, dp):
        if row == rows:
            return 0

        if col1 < 0 or col2 < 0 or col1 >= cols or col2 >= cols:
            return float('-inf')

        if dp[row][col1][col2] != -1:
            return dp[row][col1][col2]

        maxCherries = 0

        for i in range(3):
            for j in range(3):
                maxCherries = max(maxCherries, self.solve(row + 1, col1 + self.dir[i], col2 + self.dir[j], rows, cols, grid, dp))

        if col1 == col2:
            maxCherries += grid[row][col1]
        else:
            maxCherries += grid[row][col1] + grid[row][col2]

        dp[row][col1][col2] = maxCherries
        return maxCherries

    def cherryPickup(self, grid: List[List[int]]) -> int:
        rows = len(grid)
        cols = len(grid[0])
        dp = [[[-1] * cols for _ in range(cols)] for _ in range(rows)]

        return self.solve(0, 0, cols - 1, rows, cols, grid, dp)

Javascript Code

var cherryPickup = function(grid) {

    const dir = [-1, 0, 1];
    const rows = grid.length;
    const cols = grid[0].length;
    const dp = new Array(rows).fill(0).map(() => new Array(cols).fill(0).map(() => new Array(cols).fill(-1)));

    const solve = (row, col1, col2) => {
        if (row === rows) {
            return 0;
        }

        if (col1 < 0 || col2 < 0 || col1 >= cols || col2 >= cols) {
            return Number.MIN_SAFE_INTEGER;
        }

        if (dp[row][col1][col2] !== -1) {
            return dp[row][col1][col2];
        }

        let maxCherries = 0;

        for (let i = 0; i < 3; i++) {
            for (let j = 0; j < 3; j++) {
                maxCherries = Math.max(maxCherries, solve(row + 1, col1 + dir[i], col2 + dir[j]));
            }
        }

        if (col1 === col2) {
            maxCherries += grid[row][col1];
        } else {
            maxCherries += grid[row][col1] + grid[row][col2];
        }

        dp[row][col1][col2] = maxCherries;
        return maxCherries;
    };

    return solve(0, 0, cols - 1);
};

Go Code

func cherryPickup(grid [][]int) int {
	rows := len(grid)
	cols := len(grid[0])
	dp := make([][][]int, rows)
	for i := range dp {
		dp[i] = make([][]int, cols)
		for j := range dp[i] {
			dp[i][j] = make([]int, cols)
			for k := range dp[i][j] {
				dp[i][j][k] = -1
			}
		}
	}

	return solve(0, 0, cols-1, rows, cols, grid, dp)
}

func solve(row, col1, col2, rows, cols int, grid [][]int, dp [][][]int) int {
	if row == rows {
		return 0
	}

	if col1 < 0 || col2 < 0 || col1 >= cols || col2 >= cols {
		return math.MinInt32
	}

	if dp[row][col1][col2] != -1 {
		return dp[row][col1][col2]
	}

	maxCherries := 0
	for i := -1; i <= 1; i++ {
		for j := -1; j <= 1; j++ {
			maxCherries = max(maxCherries, solve(row+1, col1+i, col2+j, rows, cols, grid, dp))
		}
	}

	if col1 == col2 {
		maxCherries += grid[row][col1]
	} else {
		maxCherries += grid[row][col1] + grid[row][col2]
	}

	dp[row][col1][col2] = maxCherries
	return maxCherries
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

Complexity Analysis

Time Complexity: O(M * N2)
Space Complexity: O(M * N2)