
Minimum Cost For Tickets
28 March, 2023
5
5
1
Contributors
Problem Statement:-
You have planned some train traveling one year in advance. The days of the year in which you will travel are given as an integer array days
. Each day is an integer from 1
to 365
.
Train tickets are sold in three different ways:
- a 1-day pass is sold for
costs[0]
dollars, - a 7-day pass is sold for
costs[1]
dollars, and - a 30-day pass is sold for
costs[2]
dollars.
The passes allow that many days of consecutive travel.
- For example, if we get a 7-day pass on day
2
, then we can travel for7
days:2
,3
,4
,5
,6
,7
, and8
.
Return the minimum number of dollars you need to travel every day in the given list of days.
Link: https://leetcode.com/problems/minimum-cost-for-tickets/description/
Problem Explanation with examples:-
Example 1
Input: days = [1,4,6,7,8,20], costs = [2,7,15]
Output: 11
Explanation: For example, here is one way to buy passes that lets you travel your travel plan:
On day 1, you bought a 1-day pass for costs[0] = $2, which covered day 1.
On day 3, you bought a 7-day pass for costs[1] = $7, which covered days 3, 4, ..., 9.
On day 20, you bought a 1-day pass for costs[0] = $2, which covered day 20.
In total, you spent $11 and covered all the days of your travel.
Example 2
Input: days = [1,2,3,4,5,6,7,8,9,10,30,31], costs = [2,7,15]
Output: 17
Explanation: For example, here is one way to buy passes that lets you travel your travel plan:
On day 1, you bought a 30-day pass for costs[2] = $15 which covered days 1, 2, ..., 30.
On day 31, you bought a 1-day pass for costs[0] = $2 which covered day 31.
In total, you spent $17 and covered all the days of your travel.
Constraints
1 <= days.length <= 365
1 <= days[i] <= 365
days
is in strictly increasing order.costs.length == 3
1 <= costs[i] <= 1000
Intuition:-
- Minimum cost to travel on all given days is required.
- We can travel on any day, but we have to pay for the ticket for that day.
- We can buy a 1-day, 7-day or 30-day ticket. Then we can travel on any day within that period and select the ticket that is cheapest.
- We can use dynamic programming to solve this problem.
- We can use a dp array to store the minimum cost to travel on each day.
- A hashmap is used to store the days on which we have to travel.
- Depending on the day, we can either buy a ticket or not buy a ticket.
Solution:-
- Initialize a hashmap to store the days on which we have to travel.
- Initialize a dp array to store the minimum cost to travel on each day.
- Iterate over the days array and store the days on which we have to travel in the hashmap.
- Iterate over the dp array from index 1 to 365.
- If the day is not in the hashmap, then we can travel on that day without buying a ticket. So, the minimum cost to travel on that day is the same as the minimum cost to travel on the previous day.
- If the day is in the hashmap, then we have to buy a ticket. So, we can buy a 1-day, 7-day or 30-day ticket. Then we can travel on any day within that period and select the ticket that is cheapest.
- For a 1-day ticket, the minimum cost to travel on that day is the minimum cost to travel on the previous day plus the cost of the 1-day ticket.
- For a 7-day ticket, the minimum cost to travel on that day is the minimum cost to travel on the day 7 days before that day plus the cost of the 7-day ticket.
- For a 30-day ticket, the minimum cost to travel on that day is the minimum cost to travel on the day 30 days before that day plus the cost of the 30-day ticket.
- Return the minimum cost to travel on the last day.
Code:-
JAVA Solution
class Solution {
public int mincostTickets(int[] days, int[] costs) {
HashMap<Integer, Integer> mp = new HashMap<>();
for (int i = 0; i < days.length; i++) {
mp.put(days[i], 1);
}
int[] dp = new int[366];
for (int i = 1; i < 366; i++) {
if (mp.getOrDefault(i, 0) == 0) {
dp[i] = dp[i-1];
} else {
dp[i] = Math.min(dp[i-1] + costs[0], Math.min(dp[i-7] + costs[1], dp[i-30] + costs[2]));
}
}
return dp[365];
}
}
Python Solution
class Solution:
def mincostTickets(self, days: List[int], costs: List[int]) -> int:
mp = {}
for i in days:
mp[i] = 1
dp = [0 for i in range(366)]
for i in range(1,366):
if mp.get(i,0) == 0:
dp[i] = dp[i-1]
else:
dp[i] = min(dp[i-1]+costs[0], dp[i-7]+costs[1], dp[i-30]+costs[2])
return dp[365]
Complexity Analysis:-
TIME:-
Time complexity is O(n) where n is the number of days. We iterate over the dp array once. Accessing the hashmap is O(1) on average.
SPACE:-
Space complexity is O(n) where n is the number of days. We use a hashmap and a dp array of size 366.