Problem
Given an array where each element differs from the previous one by either +1 or -1 (a[i+1] = a[i] +/- 1
), find a local maximum or minimum in O(1) time. Also, the local max or min should not be an edge element of the array.
Examples
Example 1:
|
|
Example 2:
|
|
Example 3:
|
|
Example 4:
|
|
Solution
Method 1 - O(1) solution
The problem can be trivially solved in O(n) time and in O(log n) time using the technique in Find local minina. However, we seek an O(1) time solution, which restricts us from traversing the array.
Every next element differs from the previous by +/- 1. We will use this property.
Given that each element differs from the previous one by either +1 or -1, this property can be utilized effectively. Assume the array contains either a local maximum or a local minimum, with only one such extreme present.
Algorithm
Here is the algorithm:
- If the array has a local maximum, it first increases and then decreases.
- Calculate the hypothetical last element if the array were strictly increasing:
last_should_be = first_element + (size - 1)
. - Determine the local maximum as
local_max = (last_should_be + last_element) / 2
. - For a local minimum, calculate
last_should_be = first_element - (size - 1)
andlocal_min = (last_should_be + last_element) / 2
. - Handle edge cases where the array is completely increasing or decreasing; no local maximum or minimum exists in such scenarios.
Dry Run
Consider arr = [1, 2, 3, 4, 5, 4, 3, 2, 1]
.
If the array were entirely increasing:
- Hypothetically:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
- Actual:
[1, 2, 3, 4, 5, 4, 3, 2, 1]
Observe that the first 5 elements match in both arrays. Calculations yield (1+1)/2 = 1
, (2+2)/2 = 2
, (3+3)/2 = 3
, (4+4)/2 = 4
, and (5+5)/2 = 5
. Beyond this point, combinations such as (6, 4), (7, 3), up to (9, 1) result in (6+4)/2=5
, (7+3)/2=5
,…, (9+1)/2=5
, indicating a local maximum of 5.
This logic also applies to identifying a local minimum.
Code
|
|
|
|
Complexity
- ⏰ Time complexity:
O(1)
- 🧺 Space complexity:
O(1)