Facebook Pixel

3237. Alt and Tab Simulation 🔒

MediumArrayHash TableSimulation
Leetcode Link

Problem Description

In this problem, you are given a list of windows, each identified by a number from 1 to n. These windows are stacked on top of each other according to their initial order in the windows array, with the first element at the top and the last at the bottom. You are also provided with a list of queries. Each query requests that a specific window, identified by queries[i], be brought to the top of the stack. The task is to simulate this operation for each query and return the final order of the windows.

Intuition

The goal is to simulate moving specified windows to the top according to the given queries. To achieve the desired final window order efficiently, we can utilize an approach that processes the queries array in reverse. This ensures that windows specified later in the queries will be placed above earlier ones because they will appear earlier as we reverse process the list.

  1. Reverse Process Queries: By processing the queries array from the end to the start, we ensure that later queries, which should take precedence, are handled first. For each query, we check if the window has not already been processed and moved to the top; if not, we move it there, recording its existence in a hash table to prevent duplicates.

  2. Maintain Final Order: After handling all queries, some windows may not have been queried at all. These windows should remain in their initial relative order but appear below any windows that were moved by queries. Therefore, we append any remaining windows from the original windows list that were not moved during query processing to our result.

This approach, which uses a hash table to track which windows have already been repositioned, ensures that the solution is both efficient and straightforward, maintaining an overall time complexity that depends linearly on the sum of the lengths of windows and queries.

Solution Approach

The solution approach leverages a combination of a hash table and reverse traversal to efficiently reorder the windows based on the queries given. Here's how the algorithm is implemented:

  1. Initialize Data Structures:

    • We use a set s to keep track of windows that have already been moved to the top. This helps in avoiding duplicate operations for the same window.
    • An empty list ans is used to store the final order of windows after processing all queries.
  2. Reverse Traverse the Queries:

    • We traverse the queries list in reverse. By doing so, we can ensure that any window referred to by a later query will appear above those from earlier queries.
    • For each query q, we check if the window q has not been moved already (i.e., it's not in the set s).
    • If q is not in s, we append it to the ans list and add q to the set s.
  3. Append Remaining Windows:

    • After processing all queries, there may be some windows that were never queried. These should remain in the order they exist in the original windows list, but they will be added after those affected by the queries.
    • We iterate over the windows list and append each window to ans if it is not present in the set s.

The final list ans will now contain the windows in the correct order after all query operations:

class Solution:
    def simulationResult(self, windows: List[int], queries: List[int]) -> List[int]:
        s = set()
        ans = []
        for q in queries[::-1]:
            if q not in s:
                ans.append(q)
                s.add(q)
        for w in windows:
            if w not in s:
                ans.append(w)
        return ans

This solution efficiently achieves the desired reordering of windows using a combination of reverse list traversal and a hash table to ensure uniqueness in operations, yielding an effective and concise approach to the problem.

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 walk through an example to illustrate the solution approach for this problem.

Consider the following inputs:

  • Initial windows list: [1, 2, 3, 4, 5]
  • Queries: [3, 5, 2, 1]

Step-by-step Execution:

  1. Reverse Traverse the Queries:

    • Start with an empty list ans and an empty set s to track windows moved to the top.

    • Traverse queries in reverse order: [1, 2, 5, 3].

    • Process query 1: It's not in the set s, so append 1 to ans, making ans = [1]. Add 1 to s, so s = {1}.

    • Process query 2: Not in s, append 2 to ans, making ans = [1, 2]. Add 2 to s, so s = {1, 2}.

    • Process query 5: Not in s, append 5 to ans, making ans = [1, 2, 5]. Add 5 to s, so s = {1, 2, 5}.

    • Process query 3: Not in s, append 3 to ans, making ans = [1, 2, 5, 3]. Add 3 to s, so s = {1, 2, 3, 5}.

  2. Append Remaining Windows:

    • Iterate over the original windows list [1, 2, 3, 4, 5].

    • Append windows not in s to ans in their original order.

    • Window 1: Already in s, skip it.

    • Window 2: Already in s, skip it.

    • Window 3: Already in s, skip it.

    • Window 4: Not in s, append 4 to ans, making ans = [1, 2, 5, 3, 4].

    • Window 5: Already in s, skip it.

Final Result:

The final order of windows is [1, 2, 5, 3, 4], where the queried windows are moved to the top according to the order dictated by reversing the queries, followed by any untouched windows maintaining their initial order.

This example demonstrates the solution's ability to process windows efficiently and ensure the correct order after executing all queries.

Solution Implementation

1from typing import List
2
3class Solution:
4    def simulationResult(self, windows: List[int], queries: List[int]) -> List[int]:
5        # Create a set to track unique elements 
6        unique_elements = set()
7      
8        # Initialize a list to store the result
9        result = []
10      
11        # Iterate through queries in reverse order
12        for query in reversed(queries):
13            # Check if the query is not in the set
14            if query not in unique_elements:
15                result.append(query)
16                # Add the query to the set of unique elements
17                unique_elements.add(query)
18      
19        # Iterate through the windows list
20        for window in windows:
21            # Check if the window is not in the set
22            if window not in unique_elements:
23                result.append(window)
24      
25        # Return the compiled result list
26        return result
27
1class Solution {
2    public int[] simulationResult(int[] windows, int[] queries) {
3        int n = windows.length;  // The length of the windows array
4        boolean[] seen = new boolean[n + 1];  // Array to keep track of seen elements; 1-based indexing
5        int[] result = new int[n];  // Array to store the result
6        int index = 0;  // Current index in the result array
7      
8        // Traverse the queries array in reverse order
9        for (int i = queries.length - 1; i >= 0; --i) {
10            int query = queries[i];  // Current query element
11            if (!seen[query]) {  // If the query hasn't been seen yet
12                result[index++] = query;  // Add it to the result array
13                seen[query] = true;  // Mark it as seen
14            }
15        }
16      
17        // Traverse the windows array
18        for (int window : windows) {
19            if (!seen[window]) {  // If the window element hasn't been seen yet
20                result[index++] = window;  // Add it to the result array
21            }
22        }
23      
24        return result;  // Return the final result array
25    }
26}
27
1#include <vector>
2using namespace std;
3
4class Solution {
5public:
6    vector<int> simulationResult(vector<int>& windows, vector<int>& queries) {
7        int n = windows.size();
8        vector<bool> isAccessed(n + 1); // To keep track of accessed elements
9        vector<int> result; // The result vector storing the order of access
10
11        // Iterate over queries in reverse to update access status
12        for (int i = queries.size() - 1; i >= 0; --i) {
13            int currentQuery = queries[i];
14            if (!isAccessed[currentQuery]) {
15                isAccessed[currentQuery] = true; // Mark the element as accessed
16                result.push_back(currentQuery); // Add to result if not already accessed
17            }
18        }
19
20        // Append windows elements not accessed in queries
21        for (int window : windows) {
22            if (!isAccessed[window]) {
23                result.push_back(window); // Add window element if not accessed
24            }
25        }
26
27        return result; // Return the final access order
28    }
29};
30
1// This function takes two arrays: `windows` and `queries`.
2// It returns an array of numbers based on a simulation rule.
3function simulationResult(windows: number[], queries: number[]): number[] {
4  
5    // Get the length of the windows array.
6    const n = windows.length;
7  
8    // Create a boolean array `s` of size n+1, initialized to false.
9    // This array will track which indices have been included in the result from queries.
10    const s: boolean[] = Array(n + 1).fill(false);
11  
12    // Initialize the answer array to store the simulation results.
13    const ans: number[] = [];
14  
15    // Iterate over the queries array in reverse order.
16    for (let i = queries.length - 1; i >= 0; i--) {
17        const q = queries[i];
18      
19        // If a query index q has not been marked true, mark it and add to the result.
20        if (!s[q]) {
21            s[q] = true;
22            ans.push(q);
23        }
24    }
25  
26    // Iterate over the windows array and add elements which have not been marked in `s`.
27    for (const w of windows) {
28        if (!s[w]) {
29            ans.push(w);
30        }
31    }
32  
33    // Return the accumulated results in ans.
34    return ans;
35}
36

Time and Space Complexity

The time complexity of the code is O(n + m), where n is the length of the windows list and m is the length of the queries list. This is because each element in queries is processed once as the loop goes in reverse order, and each element in windows is processed in the second loop.

The space complexity is O(m), as the set s used to store unique elements is primarily influenced by the number of elements in queries, which can be at most m.

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

What are the most two important steps in writing a depth first search function? (Select 2)


Recommended Readings

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


Load More