Minimum Cost For Tickets

Minimum Cost For Tickets

Leetcode Daily Challenge (28th March, 2023)

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 for 7 days: 2, 3, 4, 5, 6, 7, and 8.

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.

References:-

Connect with me:-

Did you find this article valuable?

Support Leeting-LCS by becoming a sponsor. Any amount is appreciated!