2162. Minimum Cost to Set Cooking Time
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 as0954
→ 9 minutes 54 seconds - Entering
0
,0
,0
,8
→ interpreted as0008
→ 0 minutes 8 seconds - Entering
8
,0
,9
,0
→ interpreted as8090
→ 80 minutes 90 seconds - Entering
8
,1
,3
,0
→ interpreted as8130
→ 81 minutes 30 seconds
You're given:
startAt
: The digit (0-9) where your finger initially restsmoveCost
: The energy cost to move your finger from one digit to anotherpushCost
: The energy cost to push the current digittargetSeconds
: 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.
Intuition
The key insight is that any given number of seconds can potentially be represented in two different ways on the microwave:
- The standard representation: directly converting seconds to minutes and seconds (e.g., 125 seconds = 2 minutes 5 seconds)
- 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
(or0
,2
,0
,5
) - Option 2: Enter as 1 minute 65 seconds → digits:
1
,6
,5
(or0
,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:
- Calculate both possible representations:
(m, s)
and(m-1, s+60)
wherem, s = divmod(targetSeconds, 60)
- For each valid representation (minutes must be 0-99, seconds must be 0-99), calculate the cost
- 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
- 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 minutesm % 10
: ones digit of minutess // 10
: tens digit of secondss % 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
), addmoveCost
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 EvaluatorExample 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
- Digit
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
- Digit
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)
andf(m - 1, s + 60)
- Inside the
f
function:- Creating the array
arr
with 4 elements takesO(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)
- Creating the array
- The
divmod
operation isO(1)
for integer division - The
min
comparison isO(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
, andi
each useO(1)
space - The array
arr
always contains exactly 4 elements, usingO(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
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
Math for Technical Interviews How much math do I need to know for technical interviews The short answer is about high school level math Computer science is often associated with math and some universities even place their computer science department under the math faculty However the reality is that you
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Want a Structured Path to Master System Design Too? Don’t Miss This!