I encountered the following algorithmic question which has strict constraints on runtime (<10s and no large memory footprint) and I am stumped. My approach fails half the test cases.
Question
A box contains a number of items that can only br removed 1 at a time or 3 at a time.
How many ways can the box be emptied? the answer can be very large so return it as modulo of 10^9+7.
for example,there are n=7 items initially.They can be removed nine ways,as follows:
1.(1,1,1,1,1,1,1)
2.(1.1.1.1.3)
3.(1,1,1,3,1)
4.(1,1,3,1,1)
5.(1,3,1,1,1)
6.(3,1,1,1,1)
7.(1,3,3)
8.(3,1,3)
9.(3,3,1)
So the function should return 9.
Function Description:
Your function must take in a parameter, n for the number of items, and return an integer which denotes the number of ways to empty the box.
Constraints: 1<=n<=10^8
Sample cases :
Input: 1
Sample OutPut: 1
Explanation: There is only 1 way to remove 1 item. Answer=(1%1000000007)=1
Input: 7
Sample OutPut: 9
There is only 9 ways to remove 7 items
My Approach
This leads to a standard recurrence relation where f(n) = f(n-3) + f(n-1) for n > 2, so i did it as follows
def memoized_number_of_ways(dic, n):
if n not in dic:
dic[n] = memoized_number_of_ways(dic, n-3) + memoized_number_of_ways(dic, n-1)
return dic[n]
def numberOfWays(n):
# Write your code here
memoize = {1:1,2:1,3:2}
import math
ans = memoized_number_of_ways(memoize,n)
return ans % (math.pow(10,9) + 7)
However this fails on any case where n > 10**2. How can you do this problem while accomodating n up to 10^8 and in less than 10s with not much memory?