3423. Maximum Difference Between Adjacent Elements in a Circular Array
Problem Description
You are given a circular array nums
. In a circular array, the elements are arranged in a circle, meaning the first element and the last element are considered adjacent to each other.
Your task is to find the maximum absolute difference between any two adjacent elements in this circular array.
For example, if you have an array [1, 5, 3, 9]
:
- The adjacent pairs are:
(1,5)
,(5,3)
,(3,9)
, and(9,1)
(note the last pair wraps around) - The absolute differences are:
|1-5| = 4
,|5-3| = 2
,|3-9| = 6
,|9-1| = 8
- The maximum absolute difference would be
8
The solution uses Python's pairwise
function with a clever trick: it appends the first element to the end of the array (nums + [nums[0]]
) to handle the circular nature. This creates all adjacent pairs including the wrap-around pair. Then it calculates the absolute difference for each pair and returns the maximum value.
Intuition
The key insight is recognizing that in a circular array, we need to check all adjacent pairs, including the pair formed by the last and first elements.
When we think about finding the maximum difference between adjacent elements in a regular array, we would simply iterate through the array and compare each element with its next neighbor. However, the circular nature adds one extra comparison - the last element with the first element.
Instead of writing special logic to handle this wrap-around case separately, we can transform the problem into a simpler one. By appending the first element to the end of the array (nums + [nums[0]]
), we effectively "unfold" the circle into a linear sequence where all adjacent relationships are preserved, including the circular connection.
For instance, if we have [1, 5, 3, 9]
, by appending the first element we get [1, 5, 3, 9, 1]
. Now when we iterate through pairs:
(1, 5)
,(5, 3)
,(3, 9)
,(9, 1)
We naturally capture all adjacent pairs including the wrap-around without any special handling. We can then simply calculate abs(a - b)
for each pair and take the maximum. This elegant transformation reduces the circular array problem to a standard linear array problem, making the solution both simple and efficient.
Solution Approach
The solution follows a simulation approach where we traverse through all adjacent pairs in the circular array and track the maximum absolute difference.
The implementation uses a concise one-liner that combines several Python features:
-
Array Extension: We create
nums + [nums[0]]
to append the first element to the end of the array. This transforms the circular array problem into a linear one where all adjacent pairs can be accessed sequentially. -
Pairwise Iteration: The
pairwise()
function from Python's itertools (available in Python 3.10+) generates consecutive pairs from the extended array. For an array[1, 5, 3, 9, 1]
, it produces pairs:(1, 5)
,(5, 3)
,(3, 9)
,(9, 1)
. -
Absolute Difference Calculation: For each pair
(a, b)
, we calculateabs(a - b)
to get the absolute difference between adjacent elements. -
Maximum Selection: The
max()
function is applied to the generator expression to find the largest absolute difference among all adjacent pairs.
The algorithm processes each element exactly once (plus one extra comparison for the wrap-around), making it run in O(n)
time complexity where n
is the length of the array. The space complexity is O(1)
if we don't count the space used by the generator, or O(n)
if we consider the temporary extended array.
This approach elegantly handles the circular nature of the array without requiring conditional logic or special cases, making the code both readable and efficient.
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through the solution with a small example: nums = [4, 2, 8, 5]
Step 1: Identify all adjacent pairs in the circular array
- In a circular array, we have these adjacent pairs:
(4, 2)
- first and second elements(2, 8)
- second and third elements(8, 5)
- third and fourth elements(5, 4)
- fourth and first elements (wrap-around)
Step 2: Transform the circular array
- To handle the wrap-around naturally, append the first element to the end:
nums + [nums[0]]
=[4, 2, 8, 5] + [4]
=[4, 2, 8, 5, 4]
Step 3: Generate pairs from the extended array
- Using
pairwise()
on[4, 2, 8, 5, 4]
gives us:(4, 2)
(2, 8)
(8, 5)
(5, 4)
Step 4: Calculate absolute differences
- For each pair
(a, b)
, computeabs(a - b)
:abs(4 - 2) = 2
abs(2 - 8) = 6
abs(8 - 5) = 3
abs(5 - 4) = 1
Step 5: Find the maximum
- The maximum among
[2, 6, 3, 1]
is6
Therefore, the maximum absolute difference between adjacent elements in this circular array is 6.
The beauty of this approach is that by simply appending the first element to the end, we convert the circular problem into a linear one, allowing us to use standard iteration techniques without any special logic for the wrap-around case.
Solution Implementation
1from typing import List
2from itertools import pairwise
3
4class Solution:
5 def maxAdjacentDistance(self, nums: List[int]) -> int:
6 """
7 Find the maximum absolute difference between adjacent elements in a circular array.
8
9 Args:
10 nums: List of integers
11
12 Returns:
13 Maximum absolute difference between any two adjacent elements,
14 treating the array as circular (last element is adjacent to first)
15 """
16 # Create circular array by appending the first element to the end
17 circular_nums = nums + [nums[0]]
18
19 # Calculate absolute difference for each adjacent pair and return the maximum
20 # pairwise() creates consecutive pairs: (nums[0], nums[1]), (nums[1], nums[2]), ..., (nums[n-1], nums[0])
21 max_distance = max(abs(a - b) for a, b in pairwise(circular_nums))
22
23 return max_distance
24
1class Solution {
2 /**
3 * Finds the maximum absolute difference between adjacent elements in a circular array.
4 * The array is considered circular, meaning the last element is adjacent to the first element.
5 *
6 * @param nums the input integer array
7 * @return the maximum absolute difference between any two adjacent elements
8 */
9 public int maxAdjacentDistance(int[] nums) {
10 int arrayLength = nums.length;
11
12 // Initialize with the circular distance between first and last element
13 int maxDistance = Math.abs(nums[0] - nums[arrayLength - 1]);
14
15 // Iterate through the array to find maximum distance between consecutive elements
16 for (int i = 1; i < arrayLength; i++) {
17 int currentDistance = Math.abs(nums[i] - nums[i - 1]);
18 maxDistance = Math.max(maxDistance, currentDistance);
19 }
20
21 return maxDistance;
22 }
23}
24
1class Solution {
2public:
3 int maxAdjacentDistance(vector<int>& nums) {
4 // Initialize max distance with the circular distance between first and last element
5 int maxDistance = abs(nums[0] - nums.back());
6
7 // Iterate through the array to check all adjacent pairs
8 for (int i = 1; i < nums.size(); ++i) {
9 // Calculate absolute difference between current and previous element
10 int currentDistance = abs(nums[i] - nums[i - 1]);
11
12 // Update maximum distance if current distance is larger
13 maxDistance = max(maxDistance, currentDistance);
14 }
15
16 // Return the maximum adjacent distance found
17 return maxDistance;
18 }
19};
20
1/**
2 * Finds the maximum absolute difference between adjacent elements in an array,
3 * including the circular pair (first and last element)
4 * @param nums - The input array of numbers
5 * @returns The maximum absolute difference between any two adjacent elements
6 */
7function maxAdjacentDistance(nums: number[]): number {
8 // Get the length of the input array
9 const arrayLength: number = nums.length;
10
11 // Initialize with the circular distance between first and last element
12 let maxDistance: number = Math.abs(nums[0] - nums[arrayLength - 1]);
13
14 // Iterate through the array to find maximum adjacent difference
15 for (let i: number = 1; i < arrayLength; ++i) {
16 // Calculate absolute difference between current and previous element
17 const currentDistance: number = Math.abs(nums[i] - nums[i - 1]);
18
19 // Update maximum distance if current distance is larger
20 maxDistance = Math.max(maxDistance, currentDistance);
21 }
22
23 // Return the maximum adjacent distance found
24 return maxDistance;
25}
26
Time and Space Complexity
Time Complexity: O(n)
, where n
is the length of the array nums
.
The code creates a new list by concatenating nums
with [nums[0]]
, which takes O(n)
time. The pairwise
function iterates through this list once to generate consecutive pairs, resulting in n
pairs. For each pair (a, b)
, the code computes abs(a - b)
in O(1)
time. The max
function then iterates through all n
differences to find the maximum value, which also takes O(n)
time. Therefore, the overall time complexity is O(n) + O(n) + O(n) = O(n)
.
Space Complexity: O(1)
(or O(n)
depending on interpretation).
The strict space complexity is O(n)
because nums + [nums[0]]
creates a new list of size n + 1
. However, the reference answer states O(1)
, which likely refers to the auxiliary space complexity (excluding the space used for the input and temporary iterations). The pairwise
function returns a generator that yields pairs on-the-fly without storing all pairs in memory simultaneously. The generator expression inside max
also doesn't create an intermediate list. If we consider only the extra space beyond the input, the space complexity can be viewed as O(1)
since we're only storing individual pairs and differences at any given time during iteration.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Python Version Compatibility Issue
The pairwise()
function is only available in Python 3.10+. If you're using an older version of Python or submitting to a platform that doesn't support Python 3.10+, the code will fail with an ImportError
.
Solution: Implement your own pairwise logic or use alternative approaches:
# Alternative 1: Manual iteration without pairwise
class Solution:
def maxAdjacentDistance(self, nums: List[int]) -> int:
n = len(nums)
max_diff = 0
for i in range(n):
# Use modulo to handle circular indexing
next_idx = (i + 1) % n
max_diff = max(max_diff, abs(nums[i] - nums[next_idx]))
return max_diff
# Alternative 2: Using zip instead of pairwise
class Solution:
def maxAdjacentDistance(self, nums: List[int]) -> int:
circular_nums = nums + [nums[0]]
return max(abs(a - b) for a, b in zip(circular_nums, circular_nums[1:]))
2. Empty Array Handling
The current solution doesn't handle edge cases where the input array is empty or has only one element. Accessing nums[0]
on an empty array will raise an IndexError
.
Solution: Add validation for edge cases:
class Solution:
def maxAdjacentDistance(self, nums: List[int]) -> int:
if len(nums) <= 1:
return 0 # No adjacent pairs exist
circular_nums = nums + [nums[0]]
return max(abs(a - b) for a, b in pairwise(circular_nums))
3. Memory Overhead for Large Arrays
Creating nums + [nums[0]]
creates a new list that copies all elements, which can be inefficient for very large arrays.
Solution: Use an index-based approach that doesn't create a new array:
class Solution:
def maxAdjacentDistance(self, nums: List[int]) -> int:
if len(nums) <= 1:
return 0
max_diff = abs(nums[-1] - nums[0]) # Handle wrap-around case
for i in range(len(nums) - 1):
max_diff = max(max_diff, abs(nums[i] - nums[i + 1]))
return max_diff
4. Assuming Non-Empty Generator
When using max()
on a generator expression, if the generator is empty (which could happen with an empty input), it will raise a ValueError
.
Solution: Provide a default value to max()
:
class Solution:
def maxAdjacentDistance(self, nums: List[int]) -> int:
if not nums:
return 0
circular_nums = nums + [nums[0]]
return max((abs(a - b) for a, b in pairwise(circular_nums)), default=0)
What is the best way of checking if an element exists in a sorted array once in terms of time complexity? Select the best that applies.
Recommended Readings
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Runtime Overview When learning about algorithms and data structures you'll frequently encounter the term time complexity This concept is fundamental in computer science and offers insights into how long an algorithm takes to complete given a certain input size What is Time Complexity Time complexity represents the amount of time
Want a Structured Path to Master System Design Too? Don’t Miss This!