Facebook Pixel

3931. Check Adjacent Digit Differences

EasyString
LeetCode β†—

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 true if every adjacent pair satisfies this condition.
  • Return false if even one adjacent pair has an absolute difference greater than 2.

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.

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

How We Pick the Algorithm

Why Simulation / Basic DSA?

This problem maps to Simulation / Basic DSA through a short path in the full flowchart.

DirecttransformationoryesComplexdatastructure?noSimulation /Basic DSA

Following the described procedure step by step produces the solution.

Open in Flowchart

Intuition

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:

  1. Convert characters to numbers. The string s stores digits as characters, but to compute an absolute difference we need real integers. We use map(int, list(s)) to transform each character into its numeric value. For example, "123" becomes the numbers 1, 2, 3.

  2. Pair up adjacent digits. We use the pairwise helper, which takes a sequence and yields each consecutive pair. From the digits 1, 2, 3, pairwise produces the pairs (1, 2) and (2, 3). This neatly captures the idea of looking at neighboring digits without manually managing indices.

  3. Check the condition for each pair. For every pair (x, y), we compute abs(x - y) and test whether it is <= 2. This expresses the rule that the absolute difference between adjacent digits must be at most 2.

  4. Combine the results. We wrap everything in all(...), which returns true only when every pair satisfies the condition. If any single pair fails, all short-circuits and returns false immediately, 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:

Pairabs(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))
12
1class 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}
28
1class 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};
18
1/**
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}
24

Time and Space Complexity

  • Time Complexity: O(n), where n is the length of the string s. The code performs list(s) to convert the string into a list of characters, map(int, ...) to convert each character to an integer, and pairwise(...) to generate adjacent pairs. Each of these operations traverses the sequence once. The all(...) function then iterates over the pairs, checking the condition abs(x - y) <= 2 for each pair, which is also a linear traversal. Therefore, the overall time complexity is O(n).

  • Space Complexity: O(n). Although the reference answer states O(1), the list(s) call explicitly creates a new list containing all n characters of the string, which requires O(n) extra space. The map and pairwise objects are lazy iterators consuming O(1) space, and the all(...) generator expression also uses O(1) space. However, due to the materialized list from list(s), the actual space complexity is O(n). If list(s) were omitted (since strings are already iterable), the space complexity would be reduced to O(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 returns True.
  • pairwise("5") yields nothing β†’ all(...) returns True.

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 Roadmap
Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Get a Personalized Study Roadmap:

Which of these properties could exist for a graph but not a tree?


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More