Facebook Pixel

3386. Button with Longest Push Time


Problem Description

You are given a 2D array events which represents a sequence of button presses on a keyboard by a child. Each entry in the array events[i] = [index_i, time_i] indicates that the button located at index_i was pressed at time_i.

The array is sorted in ascending order based on the times at which the buttons were pressed. For each button, the time taken to press it is the difference in time between the current press and the previous press. For the very first button, the time taken is simply the time at which it was pressed.

Your task is to determine the index of the button that took the longest time to push. In the case where multiple buttons have the same longest time, you should return the smallest index.

Intuition

To solve this problem, the goal is to identify which button had the longest press time. Considering that the time difference between consecutive button presses can be calculated using the time values given in the events, the process involves:

  1. Tracking the Maximum Time: As you iterate over the list of events, compute the time difference between each consecutive pair of events.

  2. Updating the Longest Press Time: If a newly computed time difference between two events is greater than the previous maximum time recorded, update the longest press time and the corresponding button's index. If the calculated time is the same but involves a button at a smaller index, update the index as well.

  3. Single Pass Efficiency: By iterating through the list of events a single time (i.e., single pass), you track the longest time efficiently. Start from the second event to ensure you can compare each with its predecessor.

This approach guarantees you find the index of the button with the longest press time while maintaining efficiency in time complexity.

Solution Approach

The implementation of the solution uses a single pass approach, designed for efficiently identifying the button index with the longest press time from the events list.

Here’s a breakdown of the implementation:

  1. Initialization:

    • Begin by setting ans and t with the values from the first event. ans stores the index of the button currently known to have the longest press time, while t holds this press time.
  2. Iterate Through Pairwise Events:

    • Use a loop to iterate over pairs of consecutive events, (previous_event, current_event), starting from the second event.
    • Extract t1 from the previous event as the previous press time and t2 from the current event as the current press time, and i as the current index.
  3. Calculate Press Time:

    • For each pair, compute the difference d = t2 - t1, representing the time taken to press the current button.
  4. Update Conditions:

    • If d is greater than the previously recorded longest time t, update ans and t with the current index i and time d, respectively.
    • If d equals t but i is less than ans, update ans with i because you want the smallest index in case of a tie.
  5. Return the Result:

    • After processing all events, return ans, which contains the index of the button that took the longest time to push.

The solution is both simple and efficient, leveraging a straightforward loop and arithmetic operations to achieve the desired result in optimal time complexity.

Ready to land your dream job?

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

Start Evaluator

Example Walkthrough

Let's consider a small example to illustrate the solution approach. Suppose you have the following 2D array representing button presses:

events = [[0, 3], [2, 7], [1, 11], [3, 15]]

This means:

  • Button at index 0 was pressed at time 3.
  • Button at index 2 was pressed at time 7.
  • Button at index 1 was pressed at time 11.
  • Button at index 3 was pressed at time 15.

We'll follow the solution approach step-by-step:

  1. Initialization:

    • Set ans to 0, the index of the first button.
    • Set t to 3, the time at which the first button was pressed.
  2. Iterate Through Pairwise Events:

    • For each subsequent button press, calculate the time difference from the previous press.
  3. Calculate and Compare Press Time:

    • From the events [0, 3] to [2, 7]:
      • Difference d = 7 - 3 = 4
      • Since 4 is greater than t = 3, update ans = 2 and t = 4.
    • From [2, 7] to [1, 11]:
      • Difference d = 11 - 7 = 4
      • 4 equals t = 4, so compare indices. Keep ans = 2 since it’s already the smallest.
    • From [1, 11] to [3, 15]:
      • Difference d = 15 - 11 = 4
      • 4 equals t = 4, and index 3 is not less than ans = 2, so no change needed.
  4. Return the Result:

    • After processing all events, the longest press time recorded is still 4, linked to the button at the smallest index found during ties, which is 2.

Hence, the function returns 2, indicating the index of the button that took the longest time to push.

Solution Implementation

1from typing import List
2from itertools import pairwise
3
4class Solution:
5    def buttonWithLongestTime(self, events: List[List[int]]) -> int:
6        # Initialize the answer with the first button's number and time
7        ans, longest_time = events[0]
8      
9        # Iterate through pairs of events
10        for (prev_button, prev_time), (current_button, current_time) in pairwise(events):
11            # Calculate the time difference between consecutive events
12            duration = current_time - prev_time
13          
14            # Check if the current button's duration is longer than the longest
15            # or if it is the same but the button number is smaller
16            if duration > longest_time or (duration == longest_time and current_button < ans):
17                ans, longest_time = current_button, duration
18      
19        # Return the button with the longest press time
20        return ans
21
1class Solution {
2    public int buttonWithLongestTime(int[][] events) {
3        int buttonWithMaxTime = events[0][0];  // Initialize with the first button
4        int maxDuration = events[0][1];        // Initialize with the first duration
5      
6        for (int k = 1; k < events.length; ++k) {
7            int currentButton = events[k][0];  // Current button identifier
8            int currentTime = events[k][1];    // Current time stamp
9            int previousTime = events[k - 1][1]; // Previous time stamp
10          
11            int duration = currentTime - previousTime; // Calculate duration between two events
12          
13            // If the current duration is longer than the max duration found or
14            // if equal, prefer the button with the smaller identifier
15            if (duration > maxDuration || (duration == maxDuration && buttonWithMaxTime > currentButton)) {
16                buttonWithMaxTime = currentButton; 
17                maxDuration = duration;
18            }
19        }
20      
21        return buttonWithMaxTime; // Return the button that had the longest press duration
22    }
23}
24
1class Solution {
2public:
3    int buttonWithLongestTime(vector<vector<int>>& events) {
4        // Initialize 'ans' with the button id from the first event and 't' with its time
5        int ans = events[0][0];
6        int t = events[0][1];
7      
8        // Iterate over the events starting from the second one
9        for (int k = 1; k < events.size(); ++k) {
10            int currentButton = events[k][0];
11            int currentTime = events[k][1];
12            int previousTime = events[k - 1][1];
13          
14            // Calculate the duration for the current event
15            int duration = currentTime - previousTime;
16          
17            // Update the answer if the current duration is longer than 't'
18            // or if the duration is equal but the button id is smaller
19            if (duration > t || (duration == t && ans > currentButton)) {
20                ans = currentButton;
21                t = duration;
22            }
23        }
24      
25        return ans; // Return the button id with the longest time
26    }
27};
28
1/**
2 * Function to determine the button with the longest press time.
3 * @param events - An array where each element is a tuple of button index and time.
4 * @returns The index of the button with the longest press time.
5 */
6function buttonWithLongestTime(events: number[][]): number {
7    // Initialize the answer with the first button index and its time
8    let [ans, prevTime] = events[0];
9
10    // Iterate over the events starting from the second event
11    for (let k = 1; k < events.length; ++k) {
12        const [currentIndex, currentTime] = events[k];
13      
14        // Calculate the duration of the current button press
15        const duration = currentTime - events[k - 1][1];
16      
17        // Update answer if this duration is longer, or equal but has a smaller index
18        if (duration > prevTime || (duration === prevTime && currentIndex < ans)) {
19            ans = currentIndex;
20            prevTime = duration;
21        }
22    }
23
24    // Return the index of the button with the longest press time
25    return ans;
26}
27

Time and Space Complexity

The time complexity of the code is O(n), where n is the length of the array events. This is because the code iterates over the list of events only once to determine the button with the longest pressed/released time.

The space complexity is O(1), as the code uses a constant amount of additional space, regardless of the size of the input events. The variables ans and t are used to keep track of the answer and the maximum duration, which do not depend on the input size.

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


Discover Your Strengths and Weaknesses: Take Our 2-Minute Quiz to Tailor Your Study Plan:
Question 1 out of 10

Problem: Given a list of tasks and a list of requirements, compute a sequence of tasks that can be performed, such that we complete every task once while satisfying all the requirements.

Which of the following method should we use to solve this problem?


Recommended Readings

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


Load More