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:
k elements that are just before the index i are in non-increasing order.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 the array: - Index 2. The subarray [2,1] is in non-increasing order, and the subarray [1,3] is in non-decreasing order. - Index 3. The subarray [1,1] is in non-increasing order, and the subarray [3,4] is in non-decreasing order. Note that the index 4 is not good because [4,1] is not non-decreasing.
Example 2:
Input: nums = [2,1,1,2], k = 2 Output: [] Explanation: There are no good indices in this array.
Constraints:
n == nums.length3 <= n <= 1051 <= nums[i] <= 1061 <= k <= n / 2When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
To solve this problem using the brute force strategy, we will examine each position in a list to determine if it is a 'good' one. For each position, we will independently check two things: whether the numbers to its left are non-increasing and whether the numbers to its right are non-decreasing.
Here's how the algorithm would work step-by-step:
def find_all_good_indices_brute_force(numbers, sub_array_length):
good_indices = []
list_length = len(numbers)
for index_to_check in range(sub_array_length, list_length - sub_array_length):
is_good_index = True
# Check the descending condition.
for preceding_index in range(index_to_check - sub_array_length, index_to_check - 1):
if numbers[preceding_index] < numbers[preceding_index + 1]:
is_good_index = False
break
# If the preceding numbers are not descending, continue.
if not is_good_index:
continue
# Check the ascending condition.
for following_index in range(index_to_check + 1, index_to_check + sub_array_length):
if numbers[following_index] < numbers[following_index - 1]:
is_good_index = False
break
# The current index is a 'good' index.
if is_good_index:
good_indices.append(index_to_check)
return good_indicesThe core idea is to precompute information about increasing and decreasing sequences. Instead of checking the condition for each possible index, we prepare ahead of time to quickly identify the 'good' ones.
Here's how the algorithm would work step-by-step:
def find_good_indices(numbers, sub_array_length):
array_length = len(numbers)
decreasing_counts = [0] * array_length
# Calculate decreasing subsequence lengths from left.
for i in range(1, array_length):
if numbers[i] <= numbers[i - 1]:
decreasing_counts[i] = decreasing_counts[i - 1] + 1
increasing_counts = [0] * array_length
# Calculate increasing subsequence lengths from right.
for i in range(array_length - 2, -1, -1):
if numbers[i] <= numbers[i + 1]:
increasing_counts[i] = increasing_counts[i + 1] + 1
good_indices = []
# Iterate through possible good indices.
for i in range(sub_array_length, array_length - sub_array_length):
# Check if the index satisfies the conditions to be good.
if decreasing_counts[i - 1] >= sub_array_length - 1 and \
increasing_counts[i + 1] >= sub_array_length - 1:
good_indices.append(i)
return good_indices| Case | How to Handle |
|---|---|
| Empty nums array | Return an empty list since a 'good' index cannot exist. |
| k is 0 | Every index except the first and last k elements is a good index; return all indices from k to nums.length - k -1 inclusive. |
| k is greater than or equal to nums.length | Return an empty list since no index can have k elements before and after it. |
| nums.length is less than 2 * k + 1 | Return an empty list since no index can have k elements before and after it. |
| Large nums array (performance) | Optimize the solution to avoid redundant calculations, potentially using dynamic programming to precompute non-increasing/non-decreasing sequences. |
| nums array with all identical values | All indices from k to nums.length - k - 1 (inclusive) will be good indices, as the sequences will always be non-increasing and non-decreasing. |
| Integer overflow during calculation if values in `nums` are very large/small, and k is large. | Use a data type that can accommodate larger numbers or check if any intermediate value exceeds the bounds. |
| k equals to nums.length/2, resulting to a single middle index | The algorithm must correctly identify whether the single middle index meets both the non-increasing and non-decreasing conditions, returning either a list with the index, or an empty list. |