AMAZON Coding Question – Solved

4 Live
In this new stock prediction game launched on Amazon Games, Player 1 provides Player 2 with stock market data for n consecutive days, representing Amazon's stock prices on each day, represented by the array stockData. The rules of the game are as follows: 1. Player 1 will tell Player 2 a specific day number i (where 1 ≤ i ≤ n). 2. Player 2 has to find the nearest day j (1 ≤ j ≤ n, j ≠ i) in the past or future on which the stock price was lower than on the given day, i.e., stockData[j] < stockData[i]. 3. If there is more than one such j, then Player 2 must choose the one with the smallest day number. 4. If no such day j exists, the answer for that query is -1. Given q queries in the array queries, the task is to find the answer for each queries[i] in the queries and return a list of answers corresponding to each query. Example: n = 10 stockData = [5, 6, 8, 4, 9, 10, 8, 3, 6, 4] queries = [6, 5, 4] - On day 6, the stock price is 10. Both days 5 and 7 have lower prices (9 and 8 respectively). Choose day 5 because it's earlier. - On day 5, the stock price is 9. Day 4 has a lower price of 4. - On day 4, the stock price is 4. The only lower price is on day 8 (3). Thus, the output is [5, 4, 8]. Function Description: Complete the function `predictAnswer` in the editor below. `predictAnswer` has the following parameters: - int stockData[n]: An integer array where each element represents the stock price on day i+1 (0-based indexing). - int queries[q]: An array where each element is a query day number (1-based indexing). Return: - int[q]: An array of integers where each value at index i is the answer to queries[i], as per the game rules. Constraints: - 1 ≤ n ≤ 10^5 - 1 ≤ stockData[i] ≤ 10^9 - 1 ≤ q ≤ 10^5 - 1 ≤ queries[j] ≤ n

Asked in: AMAZON

Image of the Question

Question Image Question Image Question Image

All Testcases Passed ✔



Passcode Image

Solution


def predictAnswer(stockData, queries):
    # Write your code here
    def solve(arr):
        stack = []
// ... rest of solution available after purchase

🔒 Please login to view the solution

Explanation


```
To solve this problem efficiently, it's essential to understand the rules and constraints of the game. Each query asks for the closest earlier or later day with a strictly lower stock price than the current day’s stock price, and if there are multiple valid days, the one with the smaller index (day number) should be returned. If there’s no such day, the answer is -1.

Given that the stock data can be up to 100,000 elements and the number of queries can also be up to 100,000, any naive approach that scans all other days for each query would be far too slow. Instead, the focus should be on preprocessing the data in a way that allows each query to be answered in constant or logarithmic time after an initial preprocessing phase.

Let’s break this down into logical steps that help you think about the problem structurally:

**Step 1: Understand the nature of the nearest-lower-value query**

For each day `i`, you want to know:
- The nearest previous day with a strictly lower stock price.
- The nearest next day with a strictly lower stock price.
- Among those two, choose the one with the smaller day number.

This is a classic "Nearest Smaller Element" (NSE) problem variant, which is well-suited for stack-based solutions. The idea is to build two arrays:
- `prevLower[i]`: the index of the nearest day to the left of day i where the stock price is lower.
- `nextLower[i]`: the index of the nearest day to the right of day i where the stock price is lower.

These arrays can be computed efficiently in linear time using a **monotonic stack**:
- For `prevLower`, you process the stockData from left to right, maintaining a stack of indices in increasing order of their stock prices.
- For `nextLower`, you process the stockData from right to left with similar logic.

**Step 2: Preprocess stock data to compute nearest smaller indices**

During preprocessing:
- For each day, store the nearest previous day where stockData[j] < stockData[i] (if any), or -1.
- Do the same for the next day in the future.
This results in two arrays of size `n`, which will later allow constant-time query answers.

The important thing to remember during this phase is that you are looking for the **nearest** lower value, not just any lower value. The stack helps ensure you're always maintaining the most recent candidates that could satisfy this condition. The direction of iteration determines whether you're looking at previous or future days.

**Step 3: Process each query using the precomputed data**

Once both `prevLower` and `nextLower` arrays are ready, handling each query is straightforward:
- Convert the 1-based query day to a 0-based index.
- Check both `prevLower[i]` and `nextLower[i]`. If both are valid (not -1), return the one with the smaller index.
- If only one is valid, return that.
- If neither is valid, return -1.

This part is very fast since it just involves a few conditional checks and array lookups, making each query O(1) in time.

**Step 4: Think about edge cases**

Ensure your implementation correctly handles:
- Days at the beginning and end of the array (e.g., no previous or no next day).
- Repeated stock values on different days (although prices are not repeated on the same day, duplicates in different locations may exist).
- Queries that request the first or last day, which only have one direction to look in.

**Step 5: Analyze time and space complexity**

Time complexity:
- O(n) for building `prevLower` using a single pass and a stack.
- O(n) for building `nextLower` using another pass and stack.
- O(q) for answering q queries after preprocessing.
Thus, total time complexity is O(n + q), which is efficient enough given the constraints.

Space complexity:
- O(n) for `prevLower`
- O(n) for `nextLower`
- O(n) for the stack used in preprocessing
- O(q) for storing query results

This approach ensures scalability for large inputs and provides an elegant use of classical data structures to solve a real-world simulation problem.

In summary, the problem is a variation of the nearest smaller element search in two directions. Using a monotonic stack helps precompute the required information efficiently. Once the data is preprocessed, each query can be answered in constant time by simply comparing the nearest smaller values in both directions. This is a classic example of trading some upfront computation time for extremely fast query response times.
```


Related Questions