Want Help Cracking FAANG?

(Then click this)

×
Back to Question Bank

1629. Slowest Key - Leetcode Solution

Problem Description

The "Slowest Key" problem on Leetcode asks you to analyze a sequence of keypress events to determine which key was pressed for the longest duration. You are given two inputs:

  • releaseTimes: an array of integers where releaseTimes[i] represents the time at which the ith key was released.
  • keysPressed: a string where keysPressed[i] is the key pressed at the ith event.

The duration of the ith keypress is defined as releaseTimes[i] - releaseTimes[i-1] for i > 0, and releaseTimes[0] for the first key.

Your task is to determine which key had the longest duration. If there are multiple keys with the same maximum duration, return the lexicographically largest key (i.e., the one with the highest alphabetical order).

Constraints include:

  • There is always at least one key event.
  • Only one valid answer exists for the inputs.
  • All release times are strictly increasing.

Thought Process

To solve this problem, we need to compute the duration for each keypress, then find the key with the longest duration. If two or more keys share the same maximum duration, we must select the one that is lexicographically larger.

At first, you might consider iterating through all pairs of keypresses and calculating durations, but since the data is given in order and each keypress only depends on the previous release time, we can process the arrays in a single pass.

The main insight is that we do not need to store all durations; we can simply keep track of the current maximum duration and the corresponding key as we go.

Solution Approach

Let's break down the solution step by step:

  1. Initialize tracking variables: Set variables to keep track of the maximum duration found so far and the corresponding key.
  2. Iterate through the keypress events: For each event, compute the duration:
    • For the first key, the duration is releaseTimes[0].
    • For subsequent keys, the duration is releaseTimes[i] - releaseTimes[i-1].
  3. Update the maximum: If the current duration is greater than the previous maximum, update both the maximum duration and the key. If the duration is equal to the maximum, update the key only if it is lexicographically larger.
  4. Return the result: After the loop, the stored key is the answer.

We use simple variables because we only need to remember the current maximum, not all durations. Lexicographical comparison is straightforward with characters.

Example Walkthrough

Let's walk through an example:

    releaseTimes = [9, 29, 49, 50]
    keysPressed = "cbcd"
  
  1. First key: Duration = 9 (since it's the first key), key = 'c'. Max duration so far: 9, key: 'c'.
  2. Second key: Duration = 29 - 9 = 20, key = 'b'. 20 > 9, so update max duration to 20, key: 'b'.
  3. Third key: Duration = 49 - 29 = 20, key = 'c'. 20 == 20, but 'c' > 'b', so update key to 'c'.
  4. Fourth key: Duration = 50 - 49 = 1, key = 'd'. 1 < 20, so no update.

Final answer: 'c' (duration 20, which is tied but lexicographically largest).

Time and Space Complexity

  • Brute-force approach: If we were to store all durations and then search for the maximum, it would still be O(n) time and O(n) space, where n is the length of the input.
  • Optimized approach: Our solution iterates through the arrays once, so it is O(n) time and O(1) space, since we only use a constant number of variables.

The optimization comes from not storing all durations, but only tracking the maximum as we go.

Summary

The "Slowest Key" problem is an example of how careful iteration and tracking can lead to an efficient solution. By leveraging the structure of the input and the problem's constraints, we avoid unnecessary storage and computation. The key insight is to update the answer as we process each keypress, using simple comparisons for both duration and lexicographical order.

Code Implementation

class Solution:
    def slowestKey(self, releaseTimes, keysPressed):
        max_duration = releaseTimes[0]
        answer = keysPressed[0]
        for i in range(1, len(releaseTimes)):
            duration = releaseTimes[i] - releaseTimes[i-1]
            if duration > max_duration or (duration == max_duration and keysPressed[i] > answer):
                max_duration = duration
                answer = keysPressed[i]
        return answer
      
class Solution {
public:
    char slowestKey(vector<int>& releaseTimes, string keysPressed) {
        int maxDuration = releaseTimes[0];
        char answer = keysPressed[0];
        for (int i = 1; i < releaseTimes.size(); ++i) {
            int duration = releaseTimes[i] - releaseTimes[i-1];
            if (duration > maxDuration || (duration == maxDuration && keysPressed[i] > answer)) {
                maxDuration = duration;
                answer = keysPressed[i];
            }
        }
        return answer;
    }
};
      
class Solution {
    public char slowestKey(int[] releaseTimes, String keysPressed) {
        int maxDuration = releaseTimes[0];
        char answer = keysPressed.charAt(0);
        for (int i = 1; i < releaseTimes.length; i++) {
            int duration = releaseTimes[i] - releaseTimes[i - 1];
            char key = keysPressed.charAt(i);
            if (duration > maxDuration || (duration == maxDuration && key > answer)) {
                maxDuration = duration;
                answer = key;
            }
        }
        return answer;
    }
}
      
var slowestKey = function(releaseTimes, keysPressed) {
    let maxDuration = releaseTimes[0];
    let answer = keysPressed[0];
    for (let i = 1; i < releaseTimes.length; i++) {
        let duration = releaseTimes[i] - releaseTimes[i - 1];
        if (duration > maxDuration || (duration === maxDuration && keysPressed[i] > answer)) {
            maxDuration = duration;
            answer = keysPressed[i];
        }
    }
    return answer;
};