Facebook Pixel

2162. Minimum Cost to Set Cooking Time

MediumMathEnumeration
Leetcode Link

Problem Description

You have a microwave that accepts cooking time input through digit buttons (0-9). The microwave can cook for a minimum of 1 second and a maximum of 99 minutes and 99 seconds.

When setting the cooking time, you can push up to 4 digits. The microwave interprets your input by:

  • Adding leading zeros if you enter fewer than 4 digits
  • Reading the first two digits as minutes
  • Reading the last two digits as seconds

For example:

  • Entering 9, 5, 4 → interpreted as 0954 → 9 minutes 54 seconds
  • Entering 0, 0, 0, 8 → interpreted as 0008 → 0 minutes 8 seconds
  • Entering 8, 0, 9, 0 → interpreted as 8090 → 80 minutes 90 seconds
  • Entering 8, 1, 3, 0 → interpreted as 8130 → 81 minutes 30 seconds

You're given:

  • startAt: The digit (0-9) where your finger initially rests
  • moveCost: The energy cost to move your finger from one digit to another
  • pushCost: The energy cost to push the current digit
  • targetSeconds: The desired cooking time in seconds

The cost calculation works as follows:

  • If you need to push a digit different from where your finger currently is, you first pay moveCost to move to that digit
  • Then you pay pushCost to push the digit
  • Your finger stays at the last pushed digit

Your task is to find the minimum total cost to set the microwave to exactly targetSeconds of cooking time. Note that the same target time can potentially be represented in different ways (e.g., 90 seconds can be entered as either 90 seconds or 1 minute 30 seconds), and you should choose the representation that minimizes the total cost.

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

The key insight is that any given number of seconds can potentially be represented in two different ways on the microwave:

  1. The standard representation: directly converting seconds to minutes and seconds (e.g., 125 seconds = 2 minutes 5 seconds)
  2. An alternative representation: borrowing 1 minute and adding 60 seconds (e.g., 125 seconds = 1 minute 65 seconds)

Why does this matter? Because different representations require pressing different sequences of digits, which can result in different costs depending on:

  • Where your finger starts (startAt)
  • The cost of moving between digits (moveCost)
  • The cost of pushing digits (pushCost)

For example, if targetSeconds = 125:

  • Option 1: Enter as 2 minutes 5 seconds → digits: 2, 0, 5 (or 0, 2, 0, 5)
  • Option 2: Enter as 1 minute 65 seconds → digits: 1, 6, 5 (or 0, 1, 6, 5)

The cost difference between these options depends on the digit transitions required and whether we need to move our finger.

The solution approach naturally follows:

  1. Calculate both possible representations: (m, s) and (m-1, s+60) where m, s = divmod(targetSeconds, 60)
  2. For each valid representation (minutes must be 0-99, seconds must be 0-99), calculate the cost
  3. When calculating cost for a representation, we need to:
    • Convert minutes and seconds to their digit sequence
    • Skip leading zeros (we don't need to press them)
    • Track finger position and accumulate move costs and push costs
  4. Return the minimum cost among all valid representations

The constraint checking (0 <= m < 100 and 0 <= s < 100) ensures we only consider valid microwave inputs, as the microwave cannot handle values outside this range.

Learn more about Math patterns.

Solution Approach

The solution implements a helper function f(m, s) that calculates the cost for a specific minutes-seconds representation, then compares two possible representations to find the minimum cost.

Step 1: Helper Function f(m, s)

The function first validates the input:

if not 0 <= m < 100 or not 0 <= s < 100:
    return inf

This ensures both minutes and seconds are within valid microwave limits. Invalid representations return infinity to exclude them from consideration.

Step 2: Convert to Digit Array

The minutes and seconds are converted to a 4-digit array:

arr = [m // 10, m % 10, s // 10, s % 10]
  • m // 10: tens digit of minutes
  • m % 10: ones digit of minutes
  • s // 10: tens digit of seconds
  • s % 10: ones digit of seconds

For example, 9 minutes 54 seconds becomes [0, 9, 5, 4].

Step 3: Skip Leading Zeros

Since we don't need to press leading zeros, we find the first non-zero digit:

i = 0
while i < 4 and arr[i] == 0:
    i += 1

This optimization reduces unnecessary button presses.

Step 4: Calculate Total Cost

Starting from position startAt, we traverse the remaining digits:

t = 0
prev = startAt
for v in arr[i:]:
    if v != prev:
        t += moveCost
    t += pushCost
    prev = v

For each digit:

  • If it's different from our current position (v != prev), add moveCost to move there
  • Always add pushCost to press the digit
  • Update current position to this digit

Step 5: Find Minimum Cost

The main function considers both valid representations:

m, s = divmod(targetSeconds, 60)
ans = min(f(m, s), f(m - 1, s + 60))
  • divmod(targetSeconds, 60) gives the standard representation
  • We also check (m - 1, s + 60) for the alternative representation
  • Return the minimum cost between the two options

The algorithm has O(1) time complexity since we always check at most 2 representations with fixed-size digit arrays, and O(1) space complexity as we only use a few variables and a fixed-size array.

Ready to land your dream job?

Unlock your dream job with a 3-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through a concrete example with targetSeconds = 125, startAt = 2, moveCost = 3, and pushCost = 1.

Step 1: Find both possible representations

  • Standard: 125 seconds = 2 minutes, 5 seconds
  • Alternative: 125 seconds = 1 minute, 65 seconds

Step 2: Calculate cost for representation (2, 5)

  • Convert to 4-digit array: [0, 2, 0, 5]
  • Skip leading zeros: Start from index 1, so we process [2, 0, 5]
  • Calculate cost starting from position 2:
    • Digit 2: Already at position 2, no move needed. Cost = 0 + 1 (push) = 1
    • Digit 0: Move from 2 to 0. Cost = 3 (move) + 1 (push) = 4
    • Digit 5: Move from 0 to 5. Cost = 3 (move) + 1 (push) = 4
    • Total cost: 1 + 4 + 4 = 9

Step 3: Calculate cost for representation (1, 65)

  • Convert to 4-digit array: [0, 1, 6, 5]
  • Skip leading zeros: Start from index 1, so we process [1, 6, 5]
  • Calculate cost starting from position 2:
    • Digit 1: Move from 2 to 1. Cost = 3 (move) + 1 (push) = 4
    • Digit 6: Move from 1 to 6. Cost = 3 (move) + 1 (push) = 4
    • Digit 5: Move from 6 to 5. Cost = 3 (move) + 1 (push) = 4
    • Total cost: 4 + 4 + 4 = 12

Step 4: Choose minimum cost

  • Cost for (2, 5): 9
  • Cost for (1, 65): 12
  • Minimum cost: 9

In this example, entering "2 minutes 5 seconds" is cheaper than "1 minute 65 seconds" because we start at digit 2, which is exactly where we need to begin for the first representation, saving us one move operation.

Solution Implementation

1class Solution:
2    def minCostSetTime(
3        self, startAt: int, moveCost: int, pushCost: int, targetSeconds: int
4    ) -> int:
5        """
6        Calculate minimum cost to set a microwave timer to targetSeconds.
7      
8        Args:
9            startAt: Initial finger position (0-9)
10            moveCost: Cost to move finger between different digits
11            pushCost: Cost to push a digit button
12            targetSeconds: Target time in seconds
13          
14        Returns:
15            Minimum cost to set the timer
16        """
17      
18        def calculate_cost(minutes: int, seconds: int) -> int:
19            """
20            Calculate the cost to input a specific minute:second combination.
21          
22            Args:
23                minutes: Minutes to input (must be 0-99)
24                seconds: Seconds to input (must be 0-99)
25              
26            Returns:
27                Total cost to input this time, or infinity if invalid
28            """
29            # Validate that minutes and seconds are within valid range
30            if not (0 <= minutes < 100) or not (0 <= seconds < 100):
31                return float('inf')
32          
33            # Convert minutes and seconds to individual digits
34            # Format: [tens of minutes, ones of minutes, tens of seconds, ones of seconds]
35            digits = [minutes // 10, minutes % 10, seconds // 10, seconds % 10]
36          
37            # Skip leading zeros (we don't need to input them)
38            start_index = 0
39            while start_index < 4 and digits[start_index] == 0:
40                start_index += 1
41          
42            # Calculate total cost
43            total_cost = 0
44            current_position = startAt
45          
46            # Process each digit that needs to be input
47            for digit in digits[start_index:]:
48                # Add move cost if we need to move to a different digit
49                if digit != current_position:
50                    total_cost += moveCost
51                # Add push cost for pressing the button
52                total_cost += pushCost
53                # Update current position
54                current_position = digit
55          
56            return total_cost
57      
58        # Convert target seconds to minutes and seconds
59        minutes, seconds = divmod(targetSeconds, 60)
60      
61        # Try two possible representations:
62        # 1. Standard representation (m:s)
63        # 2. Alternative representation with 1 less minute and 60 more seconds (m-1:s+60)
64        min_cost = min(
65            calculate_cost(minutes, seconds),
66            calculate_cost(minutes - 1, seconds + 60)
67        )
68      
69        return min_cost
70
1class Solution {
2    /**
3     * Calculates the minimum cost to input a target time on a microwave keypad.
4     * The microwave accepts input in MM:SS format (minutes:seconds).
5     * 
6     * @param startAt The digit where the finger starts
7     * @param moveCost The cost to move the finger from one digit to another
8     * @param pushCost The cost to push a button
9     * @param targetSeconds The target time in seconds to input
10     * @return The minimum cost to input the target time
11     */
12    public int minCostSetTime(int startAt, int moveCost, int pushCost, int targetSeconds) {
13        // Calculate standard minutes and seconds representation
14        int minutes = targetSeconds / 60;
15        int seconds = targetSeconds % 60;
16      
17        // Try two possible representations:
18        // 1. Standard representation (m minutes, s seconds)
19        // 2. Alternative representation (m-1 minutes, s+60 seconds) when seconds can be > 59
20        return Math.min(
21            calculateCost(minutes, seconds, startAt, moveCost, pushCost), 
22            calculateCost(minutes - 1, seconds + 60, startAt, moveCost, pushCost)
23        );
24    }
25
26    /**
27     * Calculates the cost for a specific minute-second representation.
28     * 
29     * @param minutes The minutes value (must be 0-99)
30     * @param seconds The seconds value (must be 0-99)
31     * @param previousPosition The current finger position
32     * @param moveCost The cost to move between digits
33     * @param pushCost The cost to push a button
34     * @return The total cost, or Integer.MAX_VALUE if the representation is invalid
35     */
36    private int calculateCost(int minutes, int seconds, int previousPosition, 
37                               int moveCost, int pushCost) {
38        // Validate input: minutes and seconds must be within valid range [0, 99]
39        if (minutes < 0 || minutes > 99 || seconds < 0 || seconds > 99) {
40            return Integer.MAX_VALUE;
41        }
42      
43        // Convert minutes and seconds to individual digits
44        // Format: [tens of minutes, ones of minutes, tens of seconds, ones of seconds]
45        int[] digits = new int[] {
46            minutes / 10,  // Tens digit of minutes
47            minutes % 10,  // Ones digit of minutes
48            seconds / 10,  // Tens digit of seconds
49            seconds % 10   // Ones digit of seconds
50        };
51      
52        // Skip leading zeros (we don't need to input them)
53        int startIndex = 0;
54        while (startIndex < 4 && digits[startIndex] == 0) {
55            startIndex++;
56        }
57      
58        // Calculate total cost by iterating through digits that need to be pressed
59        int totalCost = 0;
60        for (int i = startIndex; i < 4; i++) {
61            // Add move cost if we need to move to a different digit
62            if (digits[i] != previousPosition) {
63                totalCost += moveCost;
64            }
65          
66            // Add push cost for pressing the button
67            totalCost += pushCost;
68          
69            // Update current position
70            previousPosition = digits[i];
71        }
72      
73        return totalCost;
74    }
75}
76
1class Solution {
2public:
3    int minCostSetTime(int startAt, int moveCost, int pushCost, int targetSeconds) {
4        // Calculate standard minutes and seconds representation
5        int minutes = targetSeconds / 60;
6        int seconds = targetSeconds % 60;
7      
8        // Try two possible representations:
9        // 1. Standard format: mm:ss
10        // 2. Alternative format: (m-1):(s+60) when seconds can be represented as 60+
11        int standardCost = calculateCost(minutes, seconds, startAt, moveCost, pushCost);
12        int alternativeCost = calculateCost(minutes - 1, seconds + 60, startAt, moveCost, pushCost);
13      
14        return min(standardCost, alternativeCost);
15    }
16
17private:
18    int calculateCost(int minutes, int seconds, int previousDigit, int moveCost, int pushCost) {
19        // Validate input constraints: minutes and seconds must be between 0-99
20        if (minutes < 0 || minutes > 99 || seconds < 0 || seconds > 99) {
21            return INT_MAX;
22        }
23      
24        // Convert minutes and seconds to individual digits
25        // Format: [tens of minutes, ones of minutes, tens of seconds, ones of seconds]
26        vector<int> digits = {
27            minutes / 10,  // Tens digit of minutes
28            minutes % 10,  // Ones digit of minutes
29            seconds / 10,  // Tens digit of seconds
30            seconds % 10   // Ones digit of seconds
31        };
32      
33        // Skip leading zeros (we don't need to press them)
34        int startIndex = 0;
35        while (startIndex < 4 && digits[startIndex] == 0) {
36            startIndex++;
37        }
38      
39        // Calculate total cost for pressing the required digits
40        int totalCost = 0;
41        for (int i = startIndex; i < 4; i++) {
42            // Add move cost if we need to move to a different digit
43            if (digits[i] != previousDigit) {
44                totalCost += moveCost;
45            }
46          
47            // Add push cost for pressing the current digit
48            totalCost += pushCost;
49          
50            // Update current position for next iteration
51            previousDigit = digits[i];
52        }
53      
54        return totalCost;
55    }
56};
57
1function minCostSetTime(startAt: number, moveCost: number, pushCost: number, targetSeconds: number): number {
2    // Calculate standard minutes and seconds representation
3    const minutes = Math.floor(targetSeconds / 60);
4    const seconds = targetSeconds % 60;
5  
6    // Try two possible representations:
7    // 1. Standard format: mm:ss
8    // 2. Alternative format: (m-1):(s+60) when seconds can be represented as 60+
9    const standardCost = calculateCost(minutes, seconds, startAt, moveCost, pushCost);
10    const alternativeCost = calculateCost(minutes - 1, seconds + 60, startAt, moveCost, pushCost);
11  
12    return Math.min(standardCost, alternativeCost);
13}
14
15function calculateCost(minutes: number, seconds: number, previousDigit: number, moveCost: number, pushCost: number): number {
16    // Validate input constraints: minutes and seconds must be between 0-99
17    if (minutes < 0 || minutes > 99 || seconds < 0 || seconds > 99) {
18        return Number.MAX_SAFE_INTEGER;
19    }
20  
21    // Convert minutes and seconds to individual digits
22    // Format: [tens of minutes, ones of minutes, tens of seconds, ones of seconds]
23    const digits: number[] = [
24        Math.floor(minutes / 10),  // Tens digit of minutes
25        minutes % 10,               // Ones digit of minutes
26        Math.floor(seconds / 10),  // Tens digit of seconds
27        seconds % 10                // Ones digit of seconds
28    ];
29  
30    // Skip leading zeros (we don't need to press them)
31    let startIndex = 0;
32    while (startIndex < 4 && digits[startIndex] === 0) {
33        startIndex++;
34    }
35  
36    // Calculate total cost for pressing the required digits
37    let totalCost = 0;
38    for (let i = startIndex; i < 4; i++) {
39        // Add move cost if we need to move to a different digit
40        if (digits[i] !== previousDigit) {
41            totalCost += moveCost;
42        }
43      
44        // Add push cost for pressing the current digit
45        totalCost += pushCost;
46      
47        // Update current position for next iteration
48        previousDigit = digits[i];
49    }
50  
51    return totalCost;
52}
53

Time and Space Complexity

Time Complexity: O(1)

The algorithm performs a constant number of operations regardless of the input size:

  • The f function is called exactly twice: f(m, s) and f(m - 1, s + 60)
  • Inside the f function:
    • Creating the array arr with 4 elements takes O(1) time
    • The while loop iterates at most 4 times (constant)
    • The for loop iterates over at most 4 elements (constant)
    • All operations inside both loops are O(1)
  • The divmod operation is O(1) for integer division
  • The min comparison is O(1)

Since all operations are bounded by constants and don't depend on the input size, the overall time complexity is O(1).

Space Complexity: O(1)

The algorithm uses a fixed amount of extra space:

  • Variables m, s, ans, prev, t, and i each use O(1) space
  • The array arr always contains exactly 4 elements, using O(1) space
  • The function call stack depth is constant (no recursion, just direct function calls)

The space usage doesn't scale with the input, resulting in O(1) space complexity.

Learn more about how to find time and space complexity quickly.

Common Pitfalls

1. Forgetting to Handle Edge Cases for Alternative Representations

Pitfall: When considering the alternative representation (m-1, s+60), developers often forget that this can produce invalid inputs. For example, if targetSeconds = 30, the standard representation is (0, 30), but the alternative (-1, 90) has negative minutes, which is invalid.

Solution: The code correctly handles this by validating inputs in the helper function:

if not (0 <= minutes < 100) or not (0 <= seconds < 100):
    return float('inf')

This ensures invalid representations are automatically excluded by returning infinity.

2. Incorrectly Handling Leading Zeros

Pitfall: A common mistake is either:

  • Always inputting all 4 digits (including unnecessary leading zeros)
  • Incorrectly skipping zeros that are actually required (like the zero in "0054" for 54 seconds)

Example: For 8 seconds, entering "0008" requires 4 button presses, but entering "8" requires only 1 button press.

Solution: The code correctly skips only leading zeros:

start_index = 0
while start_index < 4 and digits[start_index] == 0:
    start_index += 1

This ensures we start from the first non-zero digit or handle the special case of all zeros.

3. Not Considering Both Valid Time Representations

Pitfall: Forgetting that times like 90 seconds can be represented as either:

  • 1 minute 30 seconds (standard)
  • 0 minutes 90 seconds (alternative)

Depending on the digit positions and costs, one representation might be significantly cheaper than the other.

Solution: Always check both representations:

min_cost = min(
    calculate_cost(minutes, seconds),
    calculate_cost(minutes - 1, seconds + 60)
)

4. Incorrect Cost Calculation for Same Digit

Pitfall: Adding move cost even when the finger is already on the required digit. If the finger is on digit 5 and the next digit to press is also 5, no move cost should be added.

Solution: Only add move cost when digits differ:

if digit != current_position:
    total_cost += moveCost
total_cost += pushCost  # Always add push cost

5. Not Updating Finger Position After Each Press

Pitfall: Forgetting to track where the finger ends up after each button press, leading to incorrect move cost calculations for subsequent digits.

Solution: Always update the current position after processing each digit:

current_position = digit  # Update position after each press
Discover Your Strengths and Weaknesses: Take Our 3-Minute Quiz to Tailor Your Study Plan:

You are given an array of intervals where intervals[i] = [start_i, end_i] represent the start and end of the ith interval. You need to merge all overlapping intervals and return an array of the non-overlapping intervals that cover all the intervals in the input.


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More