LeetCode Daily Challenge-2210 Count Hills and Valleys in an Array(Easy, Two Pointers, O(n))


Problem Description
LeetCode 2210 asks us to count the number of hills and valleys in an array. A hill is an element that is strictly greater than its neighbors, while a valley is an element that is strictly smaller than its neighbors. The key challenge is handling consecutive duplicate elements - we need to treat them as a single "flat" segment and only consider the boundaries when determining hills and valleys.
Algorithm Walkthrough
The solution uses a single-pass approach with three key variables:
left
: The last distinct value we've processed (acts as the left neighbor)right
: The next distinct value (acts as the right neighbor)count
: Running total of hills and valleys found
The algorithm works as follows:
Initialize: Set
left
to the first element and iterate from index 1 to n-2 (since first and last elements can't be hills/valleys)Skip duplicates: When
nums[i] == nums[i+1]
, continue to the next iteration. This ensures we only process positions where the current element differs from the next one.Find right neighbor: Set
right = nums[i+1]
, which gives us the next distinct value.Check hill/valley conditions:
- Hill:
nums[i] > left && nums[i] > right
(current element is greater than both neighbors) - Valley:
nums[i] < left && nums[i] < right
(current element is smaller than both neighbors)
- Hill:
Update left: Set
left = nums[i]
to prepare for the next iteration.
The clever part is that by skipping duplicates and only updating left
when we find a distinct element, we effectively "compress" consecutive duplicates into single points for comparison purposes.
Complexity Analysis
- Time Complexity: O(n) where n is the length of the array. We make a single pass through the array, and each element is processed at most once.
- Space Complexity: O(1) as we only use a constant amount of extra space for the variables
left
,right
, andcount
.
Full Solution
Java
class Solution {
public int countHillValley(int[] nums) {
int n = nums.length;
int left = nums[0], right = 0, count = 0;
for (int i = 1; i < n - 1; i++) {
// Skip duplicates
if (nums[i] == nums[i + 1]) {
continue;
}
// Get right neighbor (first different from nums[i])
right = nums[i + 1];
// Check hill or valley
if ((nums[i] > left && nums[i] > right) ||
(nums[i] < left && nums[i] < right)) {
count++;
}
left = nums[i]; // Update left for next iteration
}
return count;
}
}
C
int countHillValley(int* nums, int numsSize) {
int left = nums[0], right = 0, count = 0;
for (int i = 1; i < numsSize - 1; i++) {
// Skip duplicates
if (nums[i] == nums[i + 1]) {
continue;
}
// Get right neighbor
right = nums[i + 1];
// Check hill or valley
if ((nums[i] > left && nums[i] > right) ||
(nums[i] < left && nums[i] < right)) {
count++;
}
left = nums[i];
}
return count;
}
C++
class Solution {
public:
int countHillValley(vector<int>& nums) {
int n = nums.size();
int left = nums[0], right = 0, count = 0;
for (int i = 1; i < n - 1; i++) {
// Skip duplicates
if (nums[i] == nums[i + 1]) {
continue;
}
// Get right neighbor
right = nums[i + 1];
// Check hill or valley
if ((nums[i] > left && nums[i] > right) ||
(nums[i] < left && nums[i] < right)) {
count++;
}
left = nums[i];
}
return count;
}
};
C
public class Solution {
public int CountHillValley(int[] nums) {
int n = nums.Length;
int left = nums[0], right = 0, count = 0;
for (int i = 1; i < n - 1; i++) {
// Skip duplicates
if (nums[i] == nums[i + 1]) {
continue;
}
// Get right neighbor
right = nums[i + 1];
// Check hill or valley
if ((nums[i] > left && nums[i] > right) ||
(nums[i] < left && nums[i] < right)) {
count++;
}
left = nums[i];
}
return count;
}
}
Python
class Solution:
def countHillValley(self, nums: List[int]) -> int:
n = len(nums)
left = nums[0]
count = 0
for i in range(1, n - 1):
# Skip duplicates
if nums[i] == nums[i + 1]:
continue
# Get right neighbor
right = nums[i + 1]
# Check hill or valley
if (nums[i] > left and nums[i] > right) or \
(nums[i] < left and nums[i] < right):
count += 1
left = nums[i]
return count
Golang
func countHillValley(nums []int) int {
n := len(nums)
left := nums[0]
count := 0
for i := 1; i < n-1; i++ {
// Skip duplicates
if nums[i] == nums[i+1] {
continue
}
// Get right neighbor
right := nums[i+1]
// Check hill or valley
if (nums[i] > left && nums[i] > right) ||
(nums[i] < left && nums[i] < right) {
count++
}
left = nums[i]
}
return count
}
Subscribe to my newsletter
Read articles from Anni Huang directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Anni Huang
Anni Huang
I am Anni HUANG, a software engineer with 3 years of experience in IDE development and Chatbot.