3931. Check Adjacent Digit Differences
Problem Description
You are given a string s made up of digit characters (0 through 9).
Your task is to check the digits side by side. For every pair of adjacent digits, you need to look at how far apart their values are. The "distance" between two digits a and b is the absolute difference, written as abs(a - b).
The rule is simple: the absolute difference between each pair of neighboring digits must be at most 2 (that is, 0, 1, or 2).
- Return
trueif every adjacent pair satisfies this condition. - Return
falseif even one adjacent pair has an absolute difference greater than2.
For example, in the string "123", the adjacent pairs are (1, 2) and (2, 3). Both have an absolute difference of 1, which is at most 2, so the answer would be true. In contrast, for the string "15", the pair (1, 5) has an absolute difference of 4, which is greater than 2, so the answer would be false.
How We Pick the Algorithm
Why Simulation / Basic DSA?
This problem maps to Simulation / Basic DSA through a short path in the full flowchart.
Following the described procedure step by step produces the solution.
Open in FlowchartIntuition
The problem only asks us to verify a condition about neighboring digits, so there is no need for any complex logic or clever tricks. The most natural way to think about it is to directly check exactly what the problem describes.
The key observation is that the condition must hold for every adjacent pair at the same time. This is an "all must pass" situation: if even a single pair breaks the rule, the whole string fails. This naturally points us toward walking through the string from left to right and examining each consecutive pair one by one.
To do this, we first turn each character into its numeric value, since the string stores digits as characters but we need to do arithmetic (computing abs(a - b)) on actual numbers. Once we have the digits as numbers, we look at every neighboring pair (x, y) and ask: is abs(x - y) <= 2?
If the answer is "yes" for all pairs, we can confidently return true. The moment we find a pair where the difference exceeds 2, we know the answer is false. This is exactly the kind of "check a condition over all consecutive pairs" pattern that the pairwise helper expresses cleanly, and combining it with all lets us return the final result in a single, readable line.
Solution Approach
We use a straightforward simulation strategy: we directly carry out the process the problem describes, checking each pair of adjacent digits in turn.
Here is how the implementation works step by step:
-
Convert characters to numbers. The string
sstores digits as characters, but to compute an absolute difference we need real integers. We usemap(int, list(s))to transform each character into its numeric value. For example,"123"becomes the numbers1,2,3. -
Pair up adjacent digits. We use the
pairwisehelper, which takes a sequence and yields each consecutive pair. From the digits1, 2, 3,pairwiseproduces the pairs(1, 2)and(2, 3). This neatly captures the idea of looking at neighboring digits without manually managing indices. -
Check the condition for each pair. For every pair
(x, y), we computeabs(x - y)and test whether it is<= 2. This expresses the rule that the absolute difference between adjacent digits must be at most2. -
Combine the results. We wrap everything in
all(...), which returnstrueonly when every pair satisfies the condition. If any single pair fails,allshort-circuits and returnsfalseimmediately, so we do not waste effort checking the rest.
The final one-line solution reads:
return all(abs(x - y) <= 2 for x, y in pairwise(map(int, list(s))))
In terms of complexity, we make a single pass over the string, so the time complexity is O(n), where n is the length of s. The space complexity is O(1), since the digits and pairs are generated lazily and we only ever hold a constant amount of extra data at a time.
Example Walkthrough
Let's trace through the solution using the input string s = "2468".
Step 1 β Convert characters to numbers.
The string stores digits as characters, so we first apply map(int, list(s)):
"2468" β ['2', '4', '6', '8'] β 2, 4, 6, 8
Now we have actual integers we can do arithmetic on.
Step 2 β Pair up adjacent digits.
The pairwise helper walks through the sequence and yields each consecutive pair:
From: 2, 4, 6, 8 Pairs: (2, 4), (4, 6), (6, 8)
Notice that for a sequence of 4 digits we get exactly 3 pairs β each digit is paired with its right-hand neighbor.
Step 3 β Check the condition for each pair.
For every pair (x, y), we compute abs(x - y) and test whether it is <= 2:
| Pair | abs(x - y) | <= 2? |
|---|---|---|
(2, 4) | 2 | β yes |
(4, 6) | 2 | β yes |
(6, 8) | 2 | β yes |
Step 4 β Combine the results.
Since every pair passes the check, all(...) evaluates to true, so the function returns true.
A failing example for contrast: consider s = "247".
- Digits:
2, 4, 7 - Pairs:
(2, 4)βabs = 2β , then(4, 7)βabs = 3β
The moment we hit (4, 7), the difference exceeds 2. Because of all's short-circuit behavior, we stop checking immediately and return false without examining anything further.
Solution Implementation
1from itertools import pairwise
2
3
4class Solution:
5 def isAdjacentDiffAtMostTwo(self, s: str) -> bool:
6 # Convert each character in the string to its integer value
7 digits = [int(char) for char in s]
8
9 # Use pairwise to iterate over consecutive (current, next) digit pairs
10 # Check that the absolute difference between every adjacent pair is at most 2
11 return all(abs(current - next_digit) <= 2 for current, next_digit in pairwise(digits))
121class Solution {
2 /**
3 * Checks whether every pair of adjacent characters in the string
4 * differs by at most 2 in terms of their ASCII (char) values.
5 *
6 * @param s the input string to validate
7 * @return true if all adjacent character differences are <= 2, false otherwise
8 */
9 public boolean isAdjacentDiffAtMostTwo(String s) {
10 // Iterate starting from the second character so we can always
11 // compare the current character with the previous one.
12 for (int i = 1; i < s.length(); i++) {
13 // Compute the absolute difference between the previous
14 // character and the current character.
15 int diff = Math.abs(s.charAt(i - 1) - s.charAt(i));
16
17 // If any adjacent pair differs by more than 2,
18 // the condition fails immediately.
19 if (diff > 2) {
20 return false;
21 }
22 }
23
24 // All adjacent character pairs satisfy the constraint.
25 return true;
26 }
27}
281class Solution {
2public:
3 // Returns true if every pair of adjacent characters in the string
4 // differs by at most 2 in ASCII value; otherwise returns false.
5 bool isAdjacentDiffAtMostTwo(string s) {
6 // Traverse the string starting from the second character.
7 for (int i = 1; i < s.size(); ++i) {
8 // Compare the current character with the previous one.
9 // If their absolute difference exceeds 2, the condition fails.
10 if (abs(s[i - 1] - s[i]) > 2) {
11 return false;
12 }
13 }
14 // All adjacent pairs satisfy the difference constraint.
15 return true;
16 }
17};
181/**
2 * Checks whether every pair of adjacent characters in the string
3 * differs by at most 2 (treating each character as a numeric digit).
4 *
5 * @param s - The input string composed of digit characters.
6 * @returns True if all adjacent digit differences are <= 2, otherwise false.
7 */
8function isAdjacentDiffAtMostTwo(s: string): boolean {
9 // Start from the second character and compare it with the previous one.
10 for (let i = 1; i < s.length; i++) {
11 // Convert both adjacent characters to numbers and compute their absolute difference.
12 const currentDigit: number = Number(s[i]);
13 const previousDigit: number = Number(s[i - 1]);
14
15 // If the difference exceeds 2, the condition is violated.
16 if (Math.abs(currentDigit - previousDigit) > 2) {
17 return false;
18 }
19 }
20
21 // All adjacent pairs satisfy the constraint.
22 return true;
23}
24Time and Space Complexity
-
Time Complexity:
O(n), wherenis the length of the strings. The code performslist(s)to convert the string into a list of characters,map(int, ...)to convert each character to an integer, andpairwise(...)to generate adjacent pairs. Each of these operations traverses the sequence once. Theall(...)function then iterates over the pairs, checking the conditionabs(x - y) <= 2for each pair, which is also a linear traversal. Therefore, the overall time complexity isO(n). -
Space Complexity:
O(n). Although the reference answer statesO(1), thelist(s)call explicitly creates a new list containing allncharacters of the string, which requiresO(n)extra space. Themapandpairwiseobjects are lazy iterators consumingO(1)space, and theall(...)generator expression also usesO(1)space. However, due to the materialized list fromlist(s), the actual space complexity isO(n). Iflist(s)were omitted (since strings are already iterable), the space complexity would be reduced toO(1).
Pattern Learn more about how to find time and space complexity quickly.
Common Pitfalls
Pitfall 1: Forgetting to convert characters to integers before computing the difference
The most frequent mistake is to apply abs(...) directly on the characters of the string instead of their numeric values. In Python, iterating over a string yields single-character strings (e.g., '1', '2'), not integers. Attempting abs('1' - '2') raises a TypeError because subtraction is not defined between str objects.
# WRONG: subtracting characters
return all(abs(x - y) <= 2 for x, y in pairwise(s)) # TypeError!
Even more subtly, some people try to "compare characters directly," reasoning that since '0' through '9' are consecutive in ASCII, character comparison might work. While ord('1') - ord('2') does give the correct numeric distance, comparing the raw character strings with abs is invalid, and mixing the two approaches inconsistently leads to bugs.
Solution: Always explicitly convert each character to an integer first, either with a list comprehension or map(int, s):
digits = [int(char) for char in s]
return all(abs(x - y) <= 2 for x, y in pairwise(digits))
If you genuinely want to stay in character space, use ord consistently for every character:
return all(abs(ord(x) - ord(y)) <= 2 for x, y in pairwise(s))
Both approaches produce identical results since the digit characters are contiguous in the ASCII table.
Pitfall 2: Mishandling strings of length 0 or 1 (the "no pairs" case)
A second pitfall arises when the string has fewer than two characters. If someone implements the loop manually with indices, an off-by-one error or an unguarded access like s[i + 1] can cause an IndexError. Conversely, some implementations incorrectly return false for empty or single-character strings, assuming "there must be a pair."
# WRONG: manual indexing that crashes or returns the wrong default
for i in range(len(s)):
if abs(int(s[i]) - int(s[i + 1])) > 2: # IndexError on last index
return False
return True
For a string with 0 or 1 characters, there are no adjacent pairs at all, so the condition is vacuously satisfied and the answer should be true.
Solution: The pairwise approach handles this gracefully and is the safest perspective:
pairwise("")yields nothing βall(...)over an empty iterable returnsTrue.pairwise("5")yields nothing βall(...)returnsTrue.
If you must use manual indexing, iterate only up to len(s) - 1:
for i in range(len(s) - 1):
if abs(int(s[i]) - int(s[i + 1])) > 2:
return False
return True
This range automatically becomes empty for short strings, preserving the correct vacuous-truth behavior without any special-casing.
Pitfall 3: Confusing "at most 2" with "less than 2"
A small but impactful logic error is writing the comparison as < 2 instead of <= 2. The problem explicitly allows a difference of 0, 1, or 2. Using strict < would wrongly reject a valid pair like (1, 3), whose difference is exactly 2.
# WRONG: excludes the valid difference of exactly 2
return all(abs(x - y) < 2 for x, y in pairwise(digits))
Solution: Use the inclusive comparison <= 2 to match the boundary stated in the problem:
return all(abs(x - y) <= 2 for x, y in pairwise(digits))
When in doubt, test against the boundary case directly: for the string "13", the expected output is true, which immediately exposes a < 2 mistake.
Ready to land your dream job?
Unlock your dream job with a 5-minute quiz for a personalized study roadmap!
Get My RoadmapWhich of these properties could exist for a graph but not a tree?
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 If you prefer videos here's a video that explains recursion in a fun and easy way 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 him
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 describes how the time needed
Want a Structured Path to Master System Design Too? Donβt Miss This!