Along a long library corridor, there is a line of seats and decorative plants. You are given a 0-indexed string corridor
of length n
consisting of letters 'S'
and 'P'
where each 'S'
represents a seat and each 'P'
represents a plant.
One room divider has already been installed to the left of index 0
, and another to the right of index n - 1
. Additional room dividers can be installed. For each position between indices i - 1
and i
(1 <= i <= n - 1
), at most one divider can be installed.
Divide the corridor into non-overlapping sections, where each section has exactly two seats with any number of plants. There may be multiple ways to perform the division. Two ways are different if there is a position with a room divider installed in the first way but not in the second way.
Return the number of ways to divide the corridor. Since the answer may be very large, return it modulo 109 + 7
. If there is no way, return 0
.
Example 1:
Input: corridor = "SSPPSPS" Output: 3 Explanation: There are 3 different ways to divide the corridor. The black bars in the above image indicate the two room dividers already installed. Note that in each of the ways, each section has exactly two seats.
Example 2:
Input: corridor = "PPSPSP" Output: 1 Explanation: There is only 1 way to divide the corridor, by not installing any additional dividers. Installing any would create some section that does not have exactly two seats.
Example 3:
Input: corridor = "S" Output: 0 Explanation: There is no way to divide the corridor because there will always be a section that does not have exactly two seats.
Constraints:
n == corridor.length
1 <= n <= 105
corridor[i]
is either 'S'
or 'P'
.This problem asks to find the number of ways to divide a corridor represented by a string of 'S' (seats) and 'P' (plants) into sections, each containing exactly two seats. Dividers can be placed between any two consecutive characters.
Two solutions are presented: a recursive memoization approach and a mathematical approach.
This approach uses a recursive function with memoization to explore all possible ways to place dividers.
Approach:
The core idea is to define a recursive function dfs(i, k)
where:
i
is the current index in the corridor
string.k
is the number of seats encountered so far in the current section.The base case is when i
reaches the end of the string. If k
is 2 (two seats in the current section), a valid partition is found, so it returns 1. Otherwise, it returns 0.
The recursive step considers two possibilities at each index i
:
dfs(i + 1, k)
.k == 2
), place a divider, resetting k
to 0, and recursively call dfs(i + 1, 0)
.The results of both possibilities are added (modulo 10^9 + 7
) to avoid integer overflow. Memoization (using @cache
in Python, or a f
array in other languages) stores the results of subproblems to avoid redundant computations.
Time Complexity: O(n), where n is the length of the corridor string. Each state (i, k)
is visited at most once due to memoization.
Space Complexity: O(n), due to the memoization table.
This solution leverages the mathematical properties of the problem to find a much more efficient solution.
Approach:
Count Seats: Iterate through the corridor, counting the total number of seats (cnt
). If the number of seats is odd or 0, there's no solution (return 0).
Count Ways: The key observation is that dividing the corridor into sections with two seats each only involves placing dividers between groups of seats. The number of ways to place dividers depends on the spacing between consecutive groups of two seats.
For example, if we have "SS...SS...SS", where "..." represents plants, we need to decide where to place the dividers between the "SS" groups. Suppose there are x
plants between two groups of 'SS'. Then, there are x
ways to place dividers to separate these two groups.
Calculate the result: If there's an even number of seats, calculate the product of the number of ways for each gap between the groups of seats and return the result (modulo 10^9 + 7
).
Time Complexity: O(n), since it iterates through the corridor string once.
Space Complexity: O(1), as it uses only a few constant-size variables.
This mathematical approach is significantly more efficient than the memoization approach in both time and space complexity. It's the preferred solution because of its linear time complexity and constant space complexity.