LeetCode 3285 - Find Indices of Stable Mountains
The problem asks us to find indices of "stable" mountains from a given array of mountain heights. Each element in the array represents the height of a mountain in sequence.
Difficulty: 🟢 Easy
Topics: Array
Solution
Problem Understanding
The problem asks us to find indices of "stable" mountains from a given array of mountain heights. Each element in the array represents the height of a mountain in sequence. A mountain is stable if the mountain immediately before it exists and has a height strictly greater than a given threshold. Notably, the first mountain at index 0 cannot be stable because there is no preceding mountain.
The input consists of an array of integers height and an integer threshold. The array length n can range from 2 to 100, so the problem is constrained to small arrays. Each height and threshold value is also between 1 and 100. The output should be a list of indices of all stable mountains in any order.
Edge cases to consider include situations where no mountain is stable, all mountains except the first are stable, mountains with the same height as the threshold, or alternating high and low heights.
Approaches
The most straightforward approach is brute force: iterate through each mountain starting from index 1, check the previous mountain’s height against the threshold, and collect the index if it satisfies the stable condition. This works correctly because the stable condition depends only on the previous mountain.
Given the constraints (n <= 100), the brute-force approach is efficient enough. The optimal approach is essentially the same as brute force since the problem is simple and does not require additional data structures or preprocessing.
| Approach | Time Complexity | Space Complexity | Notes |
|---|---|---|---|
| Brute Force | O(n) | O(n) | Iterate through array from index 1 and check previous element against threshold |
| Optimal | O(n) | O(n) | Same as brute force; no optimization necessary due to small input size |
Algorithm Walkthrough
- Initialize an empty list
stable_indicesto store the indices of stable mountains. - Loop through the
heightarray starting from index 1 ton-1. - For each index
i, check ifheight[i-1] > threshold. - If the condition is true, append
itostable_indices. - After the loop finishes, return
stable_indices.
Why it works: The algorithm correctly checks each mountain against the stable condition (previous mountain height strictly greater than threshold) and collects the indices. The invariant is that we examine each mountain exactly once, so no stable mountain is missed and no index is added incorrectly.
Python Solution
from typing import List
class Solution:
def stableMountains(self, height: List[int], threshold: int) -> List[int]:
stable_indices = []
for i in range(1, len(height)):
if height[i - 1] > threshold:
stable_indices.append(i)
return stable_indices
The implementation follows the algorithm exactly. We start from index 1 because mountain 0 cannot be stable. Each previous height is compared to the threshold, and if it passes, the current index is recorded.
Go Solution
func stableMountains(height []int, threshold int) []int {
stableIndices := []int{}
for i := 1; i < len(height); i++ {
if height[i-1] > threshold {
stableIndices = append(stableIndices, i)
}
}
return stableIndices
}
The Go implementation mirrors the Python version. We use a slice to collect indices and append them when the previous height is greater than the threshold. Go slices dynamically handle the storage, so we do not need to preallocate size.
Worked Examples
Example 1:
Input: height = [1,2,3,4,5], threshold = 2
| i | height[i-1] > threshold | Action | stable_indices |
|---|---|---|---|
| 1 | 1 > 2 → False | Skip | [] |
| 2 | 2 > 2 → False | Skip | [] |
| 3 | 3 > 2 → True | Append 3 | [3] |
| 4 | 4 > 2 → True | Append 4 | [3,4] |
Output: [3,4]
Example 2:
Input: height = [10,1,10,1,10], threshold = 3
| i | height[i-1] > threshold | Action | stable_indices |
|---|---|---|---|
| 1 | 10 > 3 → True | Append 1 | [1] |
| 2 | 1 > 3 → False | Skip | [1] |
| 3 | 10 > 3 → True | Append 3 | [1,3] |
| 4 | 1 > 3 → False | Skip | [1,3] |
Output: [1,3]
Complexity Analysis
| Measure | Complexity | Explanation |
|---|---|---|
| Time | O(n) | Single pass through the array to check previous heights |
| Space | O(n) | Output list stores at most n-1 indices |
Since n is at most 100, this solution is extremely efficient and does not require optimization.
Test Cases
# Provided examples
assert Solution().stableMountains([1,2,3,4,5], 2) == [3,4] # Example 1
assert Solution().stableMountains([10,1,10,1,10], 3) == [1,3] # Example 2
assert Solution().stableMountains([10,1,10,1,10], 10) == [] # Example 3
# Boundary tests
assert Solution().stableMountains([1,1], 0) == [1] # smallest array
assert Solution().stableMountains([1,1], 1) == [] # threshold equals previous height
assert Solution().stableMountains([100]*100, 50) == list(range(1,100)) # all stable except first
assert Solution().stableMountains([1]*100, 0) == list(range(1,100)) # all previous heights > 0
assert Solution().stableMountains([1]*100, 1) == [] # no previous height > threshold
| Test | Why |
|---|---|
| Example 1 | Standard case with incremental heights |
| Example 2 | Alternating high and low mountains |
| Example 3 | Threshold higher than all previous heights |
| [1,1], 0 | Minimal input size |
| [100]*100, 50 | Stress test with maximum values |
| [1]*100, 1 | Case where no mountain is stable |
Edge Cases
The first edge case is when the threshold is higher than all previous mountains. This ensures the algorithm correctly returns an empty list rather than mistakenly marking any mountain as stable. The second is when all mountains except the first are above the threshold, confirming the algorithm captures every valid index. The third is the minimal input size, where only the second mountain can potentially be stable; this tests that the algorithm correctly handles very small arrays without out-of-bounds errors. Each edge case is naturally handled by the iteration from index 1 and the strict > comparison.