Solving Leetcode Interviews in Seconds with AI: Find the Maximum Number of Fruits Collected
Introduction
In this blog post, we will explore how to solve the LeetCode problem "3363" using AI. LeetCode is a popular platform for preparing for coding interviews, and with the help of AI tools like Chatmagic, we can generate solutions quickly and efficiently - helping you pass the interviews and get the job offer without having to study for months.
Problem Statement
There is a game dungeon comprised of n x n rooms arranged in a grid. You are given a 2D array fruits of size n x n, where fruits[i][j] represents the number of fruits in the room (i, j). Three children will play in the game dungeon, with initial positions at the corner rooms (0, 0), (0, n - 1), and (n - 1, 0). The children will make exactly n - 1 moves according to the following rules to reach the room (n - 1, n - 1): The child starting from (0, 0) must move from their current room (i, j) to one of the rooms (i + 1, j + 1), (i + 1, j), and (i, j + 1) if the target room exists. The child starting from (0, n - 1) must move from their current room (i, j) to one of the rooms (i + 1, j - 1), (i + 1, j), and (i + 1, j + 1) if the target room exists. The child starting from (n - 1, 0) must move from their current room (i, j) to one of the rooms (i - 1, j + 1), (i, j + 1), and (i + 1, j + 1) if the target room exists. When a child enters a room, they will collect all the fruits there. If two or more children enter the same room, only one child will collect the fruits, and the room will be emptied after they leave. Return the maximum number of fruits the children can collect from the dungeon. Example 1: Input: fruits = [[1,2,3,4],[5,6,8,7],[9,10,11,12],[13,14,15,16]] Output: 100 Explanation: In this example: The 1st child (green) moves on the path (0,0) -> (1,1) -> (2,2) -> (3, 3). The 2nd child (red) moves on the path (0,3) -> (1,2) -> (2,3) -> (3, 3). The 3rd child (blue) moves on the path (3,0) -> (3,1) -> (3,2) -> (3, 3). In total they collect 1 + 6 + 11 + 16 + 4 + 8 + 12 + 13 + 14 + 15 = 100 fruits. Example 2: Input: fruits = [[1,1],[1,1]] Output: 4 Explanation: In this example: The 1st child moves on the path (0,0) -> (1,1). The 2nd child moves on the path (0,1) -> (1,1). The 3rd child moves on the path (1,0) -> (1,1). In total they collect 1 + 1 + 1 + 1 = 4 fruits. Constraints: 2 <= n == fruits.length == fruits[i].length <= 1000 0 <= fruits[i][j] <= 1000
Explanation
Here's the breakdown of the approach, complexities, and the Python code for the problem:
High-Level Approach:
- Dynamic Programming: Use dynamic programming to store the maximum fruits collected by each child at each possible cell they can reach. The state will be
dp[child_id][row][col]representing the maximum fruits childchild_idcan collect ending at position(row, col). - Iterative Calculation: Iterate through the grid, calculating the maximum fruits for each child at each cell based on the maximum fruits from the possible previous cells, as dictated by the movement rules. Handle the first cell for each child separately.
- Collision Handling: When multiple children reach the same cell, choose only one child to collect the fruits at that cell in the current state. The overall algorithm implicitly searches for the best possible choice.
- Dynamic Programming: Use dynamic programming to store the maximum fruits collected by each child at each possible cell they can reach. The state will be
Complexity:
- Runtime Complexity: O(n3), where n is the size of the grid. This is due to the three nested loops in the DP calculation (one for each child, and then iterations over rows and cols).
- Storage Complexity: O(n2), due to the three DP tables we use, each of size n x n.
Code
def max_fruits_collected(fruits):
"""
Calculates the maximum number of fruits three children can collect in a dungeon.
Args:
fruits: A 2D list representing the number of fruits in each room.
Returns:
The maximum number of fruits the children can collect.
"""
n = len(fruits)
# Initialize DP tables for each child
dp1 = [[0] * n for _ in range(n)] # Child 1 (0, 0)
dp2 = [[0] * n for _ in range(n)] # Child 2 (0, n-1)
dp3 = [[0] * n for _ in range(n)] # Child 3 (n-1, 0)
# Initialize starting positions
dp1[0][0] = fruits[0][0]
dp2[0][n - 1] = fruits[0][n - 1]
dp3[n - 1][0] = fruits[n - 1][0]
# Iterate through the grid
for i in range(n):
for j in range(n):
# Skip the first rooms which are initialized already
if (i == 0 and j == 0) or (i == 0 and j == n - 1) or (i == n - 1 and j == 0):
continue
# Calculate possible paths for each child
# Child 1
options1 = []
if i > 0 and j > 0:
options1.append(dp1[i - 1][j - 1])
if i > 0:
options1.append(dp1[i - 1][j])
if j > 0:
options1.append(dp1[i][j - 1])
# Child 2
options2 = []
if i > 0 and j > 0:
options2.append(dp2[i - 1][j - 1])
if i > 0 and j < n - 1:
options2.append(dp2[i - 1][j + 1])
if i > 0:
options2.append(dp2[i - 1][j])
# Child 3
options3 = []
if i < n - 1 and j > 0:
options3.append(dp3[i + 1][j - 1])
if j > 0:
options3.append(dp3[i][j - 1])
if i < n - 1:
options3.append(dp3[i + 1][j])
# Calculate maximum fruits considering collisions
max_fruits = 0
# Iterate through all possible "who picks up the fruit" scenarios:
for c1 in ([0] if not options1 else [max(options1)]):
for c2 in ([0] if not options2 else [max(options2)]):
for c3 in ([0] if not options3 else [max(options3)]):
if c1 > 0 or c2 > 0 or c3 > 0:
# At most one child takes the fruit
if c1 >= c2 and c1 >= c3 and c1 > 0:
current_fruits = c1 + fruits[i][j] if (i != n-1 or j != n-1) else c1
elif c2 >= c1 and c2 >= c3 and c2 > 0 :
current_fruits = c2 + fruits[i][j] if (i != n-1 or j != n-1) else c2
elif c3 >= c1 and c3 >= c2 and c3 > 0:
current_fruits = c3 + fruits[i][j] if (i != n-1 or j != n-1) else c3
else: # no one pick up
current_fruits = c1 + c2 + c3
else:
current_fruits = c1 + c2 + c3
max_fruits = max(max_fruits, current_fruits)
if len(options1) > 0:
dp1[i][j] = max(options1) + (fruits[i][j] if dp1[i][j] == 0 else 0)
if len(options2) > 0:
dp2[i][j] = max(options2) + (fruits[i][j] if dp2[i][j] == 0 else 0)
if len(options3) > 0:
dp3[i][j] = max(options3) + (fruits[i][j] if dp3[i][j] == 0 else 0)
# Calculate the total maximum fruits collected at the final room (n-1, n-1)
return dp1[n - 1][n - 1] + dp2[n - 1][n - 1] + dp3[n - 1][n - 1] - 2 * fruits[n - 1][n - 1]