#1444

Number of Ways of Cutting a Pizza

Hard
ArrayDynamic ProgrammingMemoizationMatrixPrefix SumDynamic ProgrammingMemoizationPrefix Sum
LeetCode ↗

Approaches

Brute ForceOptimal
Complexity Comparison
Brute ForceOptimal Solution
Time
O(n² * k)
O(n² * k)
Space
O(1)
O(n²)
💡

Intuition

Time O(n² * k)Space O(n²)

The optimal approach uses dynamic programming to store results of subproblems, reducing redundant calculations. We maintain a prefix sum array to quickly check if a piece contains apples.

⚙️

Algorithm

3 steps
  1. 1Step 1: Create a prefix sum array to count apples in any subrectangle of the pizza.
  2. 2Step 2: Use a recursive function with memoization to count ways to cut the pizza, checking each possible cut.
  3. 3Step 3: Return the result from the memoized function.
solution.py34 lines
1# Full working Python code
2from typing import List
3
4class Solution:
5    def waysToCutPizza(self, pizza: List[str], k: int) -> int:
6        MOD = 10**9 + 7
7        rows, cols = len(pizza), len(pizza[0])
8        prefix = [[0] * (cols + 1) for _ in range(rows + 1)]
9
10        # Calculate prefix sum of apples
11        for r in range(rows - 1, -1, -1):
12            for c in range(cols - 1, -1, -1):
13                prefix[r][c] = (1 if pizza[r][c] == 'A' else 0) + prefix[r + 1][c] + prefix[r][c + 1] - prefix[r + 1][c + 1]
14
15        memo = {}  # Memoization dictionary
16
17        def dfs(r1, c1, cuts_left):
18            if cuts_left == 0:
19                return 1 if prefix[r1][c1] > 0 else 0
20            if (r1, c1, cuts_left) in memo:
21                return memo[(r1, c1, cuts_left)]
22            ways = 0
23            # Horizontal cuts
24            for r in range(r1 + 1, rows):
25                if prefix[r1][c1] - prefix[r][c1] > 0:
26                    ways = (ways + dfs(r, c1, cuts_left - 1)) % MOD
27            # Vertical cuts
28            for c in range(c1 + 1, cols):
29                if prefix[r1][c1] - prefix[r1][c] > 0:
30                    ways = (ways + dfs(r1, c, cuts_left - 1)) % MOD
31            memo[(r1, c1, cuts_left)] = ways
32            return ways
33
34        return dfs(0, 0, k - 1)

Complexity note: The complexity arises from calculating the prefix sums and the recursive calls, but memoization significantly reduces redundant calculations.

  • 1Understanding prefix sums helps in quickly checking for apples in subregions.
  • 2Dynamic programming with memoization avoids recalculating results for the same state.

Solutions and explanations are original Tejav content. Problem titles © LeetCode — use the LeetCode button above for the full problem statement.