There are n uniquely-sized sticks whose lengths are integers from 1 to n. You want to arrange the sticks such that exactly k sticks are visible from the left. A stick is visible from the left if there are no longer sticks to the left of it.
[1,3,2,5,4], then the sticks with lengths 1, 3, and 5 are visible from the left.Given n and k, return the number of such arrangements. Since the answer may be large, return it modulo 109 + 7.
Example 1:
Input: n = 3, k = 2 Output: 3 Explanation: [1,3,2], [2,3,1], and [2,1,3] are the only arrangements such that exactly 2 sticks are visible. The visible sticks are underlined.
Example 2:
Input: n = 5, k = 5 Output: 1 Explanation: [1,2,3,4,5] is the only arrangement such that all 5 sticks are visible. The visible sticks are underlined.
Example 3:
Input: n = 20, k = 11 Output: 647427950 Explanation: There are 647427950 (mod 109 + 7) ways to rearrange the sticks such that exactly 11 sticks are visible.
Constraints:
1 <= n <= 10001 <= k <= nWhen you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The core idea is to try every possible arrangement of sticks. We then count how many arrangements have exactly the required number of visible sticks. This is very inefficient, but guaranteed to find the answer.
Here's how the algorithm would work step-by-step:
import itertools
def number_of_ways_brute_force(number_of_sticks, number_of_visible_sticks):
number_of_arrangements = 0
sticks = list(range(1, number_of_sticks + 1))
# Iterate through all possible permutations
for permutation in itertools.permutations(sticks):
visible_sticks_count = 0
tallest_stick_seen_so_far = 0
# Iterate through each stick in the current arrangement
for stick in permutation:
# If current stick is taller, it is visible
if stick > tallest_stick_seen_so_far:
visible_sticks_count += 1
tallest_stick_seen_so_far = stick
# Check if this arrangement matches the number of visible sticks
if visible_sticks_count == number_of_visible_sticks:
number_of_arrangements += 1
return number_of_arrangementsThe core idea is to build the solution incrementally using dynamic programming. We consider adding one stick at a time and see how it affects the number of visible sticks, avoiding recalculating redundant information.
Here's how the algorithm would work step-by-step:
def rearrange_sticks(number_of_sticks, number_of_visible_sticks):
modulo = 10**9 + 7
# Table to store the number of ways for each subproblem.
dp_table = [[0] * (number_of_visible_sticks + 1) for _ in range(number_of_sticks + 1)]
dp_table[0][0] = 1
for current_stick_count in range(1, number_of_sticks + 1):
for current_visible_count in range(1, number_of_visible_sticks + 1):
# If the tallest stick is visible, it must be at the beginning.
dp_table[current_stick_count][current_visible_count] = dp_table[current_stick_count - 1][current_visible_count - 1]
# If the tallest stick is hidden, it can be in any of the other positions.
if current_stick_count > 1:
dp_table[current_stick_count][current_visible_count] += (dp_table[current_stick_count - 1][current_visible_count] * (current_stick_count - 1)) % modulo
dp_table[current_stick_count][current_visible_count] %= modulo
# The result is stored in the bottom-right cell.
return dp_table[number_of_sticks][number_of_visible_sticks]| Case | How to Handle |
|---|---|
| n = 0, k > 0 | Return 0 as there are no sticks to arrange to have any visible. |
| n > 0, k = 0 | Return 0 as we must have at least one stick visible. |
| n = 1, k = 1 | Return 1 as there is only one arrangement with one visible stick. |
| n > 0, k > n | Return 0 as it's impossible to have more visible sticks than total sticks. |
| n and k are moderately large (e.g., n = 50, k = 25) | Dynamic programming handles this without stack overflow or excessive recursion; memoization is key. |
| Integer overflow in intermediate calculations for larger n and k | Use modulo operator throughout calculation to prevent exceeding the integer limit. |
| n and k are both very large and close to each other (e.g., n = 1000, k = 999) | Ensure the dynamic programming table is large enough to accommodate large values of n and k without causing an out-of-bounds error. |
| k = 1 and n > 0 | The visible stick must be the tallest; return (n-1)! ways to arrange the others. |