Find All Good Indices - Complete Solution Guide
Find All Good Indices is LeetCode problem 2420, a Medium level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.
Problem Statement
You are given a 0-indexed integer array nums of size n and a positive integer k . We call an index i in the range k <= i < n - k good if the following conditions are satisfied: The k elements that are just before the index i are in non-increasing order. The k elements that are just after the index i are in non-decreasing order. Return an array of all good indices sorted in increasing order . Example 1: Input: nums = [2,1,1,1,3,4,1], k = 2 Output: [2,3] Explanation: There are two good indices in
Detailed Explanation
The problem asks us to identify "good" indices in an array `nums`. An index `i` is considered "good" if it satisfies two conditions: 1) The `k` elements immediately before index `i` are in non-increasing order (each element is less than or equal to the preceding element), and 2) The `k` elements immediately after index `i` are in non-decreasing order (each element is greater than or equal to the preceding element). The index `i` must also be within the range `k <= i < n - k`, where `n` is the length of `nums`. The function should return a sorted list of all good indices.
Solution Approach
The solution uses dynamic programming to efficiently determine if each index is "good". It calculates two arrays: `non_inc` and `non_dec`. `non_inc[i]` stores the length of the longest non-increasing sequence ending at index `i`. `non_dec[i]` stores the length of the longest non-decreasing sequence starting at index `i`. Then, the code iterates through all possible "good" indices (from `k` to `n - k - 1`) and checks if `non_inc[i - 1]` and `non_dec[i + 1]` are both greater than or equal to `k`. If they are, the index `i` is added to the result list.
Step-by-Step Algorithm
- Step 1: Initialize two arrays, `non_inc` and `non_dec`, of the same size as `nums`, with all elements set to 1. This represents the base case where each element by itself forms a sequence of length 1.
- Step 2: Calculate the `non_inc` array from left to right. For each index `i`, if `nums[i] <= nums[i - 1]`, then the non-increasing sequence extends, and `non_inc[i]` becomes `non_inc[i - 1] + 1`. Otherwise, `non_inc[i]` remains 1, indicating a new sequence.
- Step 3: Calculate the `non_dec` array from right to left. For each index `i` (starting from `n - 2`), if `nums[i] <= nums[i + 1]`, then the non-decreasing sequence extends, and `non_dec[i]` becomes `non_dec[i + 1] + 1`. Otherwise, `non_dec[i]` remains 1, indicating a new sequence.
- Step 4: Iterate through the indices from `k` to `n - k - 1`. For each index `i`, check if `non_inc[i - 1] >= k` and `non_dec[i + 1] >= k`. If both conditions are true, add index `i` to the result list.
- Step 5: Return the result list, which contains all the good indices.
Key Insights
- Insight 1: The core idea is to precompute two arrays: one storing the lengths of non-increasing sequences ending at each index from the left, and another storing the lengths of non-decreasing sequences ending at each index from the right. This avoids repeatedly checking the sequences around each possible index.
- Insight 2: Dynamic Programming can be efficiently applied to build the non-increasing and non-decreasing arrays. This reduces redundant computations.
- Insight 3: Only indices `k <= i < n - k` need to be checked, as indices outside this range cannot satisfy the condition of having `k` elements before and after them.
Complexity Analysis
Time Complexity: O(n)
Space Complexity: O(n)
Topics
This problem involves: Array, Dynamic Programming, Prefix Sum.
Companies
Asked at: ByteDance, Goldman Sachs.