Numbers with one absolute difference

Last Updated : 29 Jul, 2026

Given an integer n, return all numbers less than or equal to n in increasing order such that the absolute difference between adjacent digits of every number is exactly 1.

Note:  Only numbers with at least two digits are considered valid.

Examples:

Input: n = 20
Output: [10, 12]
Explanation: The absolute difference between adjacent digits in 10 is |1 - 0| = 1, and in 12 is |1 - 2| = 1.

Input: n = 9
Output: []
Explanation: No such valid number exist in the range 1 to 9. 

Try It Yourself
redirect icon

[Naive Approach] Check Every Number - O(n × d) Time and O(1) Space

The idea is to iterate through every number from 10 to n and check whether the absolute difference between every pair of adjacent digits is exactly 1. If the condition is satisfied, include the number in the result; otherwise, ignore it.

Working of Approach:

  • Traverse every number from 10 to n.
  • Extract adjacent digits one by one using modulo and division.
  • Check whether the absolute difference of every adjacent digit pair is 1.
  • If all pairs satisfy the condition, add the number to the answer.
  • Return the final list.
C++
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;

// Function to check whether adjacent digits differ by exactly 1.
bool isValid(int num)
{

    while (num >= 10)
    {
        int last = num % 10;
        int secondLast = (num / 10) % 10;

        if (abs(last - secondLast) != 1)
            return false;

        num /= 10;
    }

    return true;
}

vector<int> absDifOne(int n)
{

    vector<int> res;

    // Check every number from 10 to n.
    for (int i = 10; i <= n; i++)
    {
        if (isValid(i))
            res.push_back(i);
    }

    return res;
}

int main()
{

    int n = 20;

    vector<int> res = absDifOne(n);

    cout << "[";

    for (int i = 0; i < res.size(); i++)
    {
        cout << res[i];
        if (i + 1 < res.size())
            cout << ", ";
    }

    cout << "]";

    return 0;
}
Java
import java.util.ArrayList;
import java.util.Arrays;

public class GFG {
    // Function to check whether adjacent digits differ by
    // exactly 1.
    public static boolean isValid(int num)
    {
        while (num >= 10) {
            int last = num % 10;
            int secondLast = (num / 10) % 10;
            if (Math.abs(last - secondLast) != 1)
                return false;
            num /= 10;
        }
        return true;
    }

    public static ArrayList<Integer> absDifOne(int n)
    {
        ArrayList<Integer> res = new ArrayList<>();
        // Check every number from 10 to n.
        for (int i = 10; i <= n; i++) {
            if (isValid(i))
                res.add(i);
        }
        return res;
    }

    public static void main(String[] args)
    {
        int n = 20;
        ArrayList<Integer> res = absDifOne(n);
        System.out.println(res);
    }
}
Python
def isValid(num):
    while num >= 10:
        last = num % 10
        secondLast = (num // 10) % 10
        if abs(last - secondLast) != 1:
            return False
        num //= 10
    return True


def absDifOne(n):
    res = []
    # Check every number from 10 to n.
    for i in range(10, n + 1):
        if isValid(i):
            res.append(i)
    return res


if __name__ == '__main__':
    n = 20
    res = absDifOne(n)
    print(res)
C#
using System;
using System.Collections.Generic;

class GFG {
    // Function to check whether adjacent digits differ by
    // exactly 1.
    static bool isValid(int num)
    {
        while (num >= 10) {
            int last = num % 10;
            int secondLast = (num / 10) % 10;

            if (Math.Abs(last - secondLast) != 1)
                return false;

            num /= 10;
        }

        return true;
    }

    static List<int> absDifOne(int n)
    {
        List<int> res = new List<int>();

        // Check every number from 10 to n.
        for (int i = 10; i <= n; i++) {
            if (isValid(i))
                res.Add(i);
        }

        return res;
    }

    static void Main(string[] args)
    {
        int n = 20;

        List<int> res = absDifOne(n);

        Console.Write("[");

        for (int i = 0; i < res.Count; i++) {
            Console.Write(res[i]);
            if (i + 1 < res.Count)
                Console.Write(", ");
        }

        Console.Write("]");
    }
}
JavaScript
function isValid(num)
{
    while (num >= 10) {
        let last = num % 10;
        let secondLast = Math.floor(num / 10) % 10;
        if (Math.abs(last - secondLast) !== 1)
            return false;
        num = Math.floor(num / 10);
    }
    return true;
}

function absDifOne(n)
{
    let res = [];
    // Check every number from 10 to n.
    for (let i = 10; i <= n; i++) {
        if (isValid(i))
            res.push(i);
    }
    return res;
}

// Driver Code
let n = 20;
let res = absDifOne(n);
console.log(res);

Output
[10, 12]

Time Complexity: O(n × d), where d is the number of digits.
Space Complexity: O(1)

[Expected Approach] Generate Valid Numbers using BFS - O(k) Time and O(k) Space

The idea is to generate only the valid numbers instead of checking every number. Start BFS from all one-digit numbers (1 to 9). For every number, append lastDigit - 1 and lastDigit + 1 whenever possible to form the next valid numbers. Continue until the generated numbers become greater than n.

For every stepping number curr, let lastDigit = curr % 10. The next possible numbers can only be formed by appending:

  • lastDigit - 1
  • lastDigit + 1

This is because the newly formed last adjacent pair must differ by exactly 1.

Suppose the last digit of curr is d.. Since curr is already a stepping number, all its previous adjacent digit pairs already satisfy the condition. Appending only changes the last adjacent pair, which also has a difference of 1. Therefore, the newly formed number is guaranteed to be a valid stepping number.

The only exceptions occur when the last digit is:

  • 0 -> Only 1 can be appended.
  • 9 -> Only 8 can be appended.

Thus, every stepping number generates at most two valid stepping numbers, making BFS an efficient way to enumerate all stepping numbers up to n.

Working of Approach:

  • Push all one-digit numbers (1 to 9) into a queue.
  • Remove one number at a time from the queue.
  • If the current number has at least two digits and is not greater than n, store it in the answer.
  • Generate new numbers by appending lastDigit - 1 and lastDigit + 1.
  • Repeat until the queue becomes empty.

Let us understand with an example:
Input: n = 20

  • Initialize the queue with all one-digit numbers: 1, 2, 3, ..., 9.
  • Remove 1 from the queue and generate 10 and 12 by appending 0 and 2; both are added to the queue.
  • Continue processing the remaining numbers in the queue. Numbers such as 21, 23, 32, and so on are generated, but since they are greater than 20, they are ignored.
  • Whenever a number greater than 20 is removed from the queue, it is ignored and no further processing is done for it.
  • The only generated valid numbers less than or equal to 20 are 10 and 12, so the output is [10, 12].
C++
#include <iostream>
#include <vector>
#include <queue>
using namespace std;

vector<int> absDifOne(int n)
{
    vector<int> res;
    queue<int> q;

    // Push all single-digit numbers into the queue.
    for (int i = 1; i <= 9; i++)
    {
        q.push(i);
    }

    while (!q.empty())
    {
        int curr = q.front();
        q.pop();

        // Skip numbers greater than n.
        if (curr > n)
        {
            continue;
        }

        // Store valid numbers having at least two digits.
        if (curr > 9)
        {
            res.push_back(curr);
        }

        int lastDigit = curr % 10;

        // Generate the next number with lastDigit - 1.
        if (lastDigit > 0)
        {
            q.push(curr * 10 + lastDigit - 1);
        }

        // Generate the next number with lastDigit + 1.
        if (lastDigit < 9)
        {
            q.push(curr * 10 + lastDigit + 1);
        }
    }

    return res;
}

int main()
{

    int n = 20;

    vector<int> res = absDifOne(n);

    cout << "[";

    for (int i = 0; i < res.size(); i++)
    {
        cout << res[i];
        if (i + 1 < res.size())
            cout << ", ";
    }

    cout << "]";

    return 0;
}
Java
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;

public class GFG {
    public static ArrayList<Integer> absDifOne(int n)
    {
        ArrayList<Integer> res = new ArrayList<>();
        Queue<Integer> q = new LinkedList<>();

        // Push all single-digit numbers into the queue.
        for (int i = 1; i <= 9; i++) {
            q.add(i);
        }

        while (!q.isEmpty()) {
            int curr = q.poll();

            // Skip numbers greater than n.
            if (curr > n) {
                continue;
            }

            // Store valid numbers having at least two
            // digits.
            if (curr > 9) {
                res.add(curr);
            }

            int lastDigit = curr % 10;

            // Generate the next number with lastDigit - 1.
            if (lastDigit > 0) {
                q.add(curr * 10 + lastDigit - 1);
            }

            // Generate the next number with lastDigit + 1.
            if (lastDigit < 9) {
                q.add(curr * 10 + lastDigit + 1);
            }
        }

        return res;
    }

    public static void main(String[] args)
    {
        int n = 20;
        ArrayList<Integer> res = absDifOne(n);

        System.out.print("[");

        for (int i = 0; i < res.size(); i++) {
            System.out.print(res.get(i));
            if (i + 1 < res.size())
                System.out.print(", ");
        }

        System.out.print("]");
    }
}
Python
from collections import deque


def absDifOne(n):
    res = []
    q = deque()

    # Push all single-digit numbers into the queue.
    for i in range(1, 10):
        q.append(i)

    while q:
        curr = q.popleft()

        # Skip numbers greater than n.
        if curr > n:
            continue

        # Store valid numbers having at least two digits.
        if curr > 9:
            res.append(curr)

        lastDigit = curr % 10

        # Generate the next number with lastDigit - 1.
        if lastDigit > 0:
            q.append(curr * 10 + lastDigit - 1)

        # Generate the next number with lastDigit + 1.
        if lastDigit < 9:
            q.append(curr * 10 + lastDigit + 1)

    return res


if __name__ == "__main__":
    n = 20
    res = absDifOne(n)

    print('[', end='')

    for i in range(len(res)):
        print(res[i], end='')
        if i + 1 < len(res):
            print(', ', end='')

    print(']')
C#
using System;
using System.Collections.Generic;
using System.Linq;

public class GFG {
    public static List<int> absDifOne(int n)
    {
        List<int> res = new List<int>();
        Queue<int> q = new Queue<int>();

        // Push all single-digit numbers into the queue.
        for (int i = 1; i <= 9; i++) {
            q.Enqueue(i);
        }

        while (q.Count > 0) {
            int curr = q.Dequeue();

            // Skip numbers greater than n.
            if (curr > n) {
                continue;
            }

            // Store valid numbers having at least two
            // digits.
            if (curr > 9) {
                res.Add(curr);
            }

            int lastDigit = curr % 10;

            // Generate the next number with lastDigit - 1.
            if (lastDigit > 0) {
                q.Enqueue(curr * 10 + lastDigit - 1);
            }

            // Generate the next number with lastDigit + 1.
            if (lastDigit < 9) {
                q.Enqueue(curr * 10 + lastDigit + 1);
            }
        }

        return res;
    }

    public static void Main()
    {
        int n = 20;
        List<int> res = absDifOne(n);

        Console.Write("[");

        for (int i = 0; i < res.Count; i++) {
            Console.Write(res[i]);
            if (i + 1 < res.Count)
                Console.Write(", ");
        }

        Console.Write("]");
    }
}
JavaScript
function absDifOne(n)
{
    let res = [];
    let q = [];

    // Push all single-digit numbers into the queue.
    for (let i = 1; i <= 9; i++) {
        q.push(i);
    }

    while (q.length > 0) {
        let curr = q.shift();

        // Skip numbers greater than n.
        if (curr > n) {
            continue;
        }

        // Store valid numbers having at least two digits.
        if (curr > 9) {
            res.push(curr);
        }

        let lastDigit = curr % 10;

        // Generate the next number with lastDigit - 1.
        if (lastDigit > 0) {
            q.push(curr * 10 + lastDigit - 1);
        }

        // Generate the next number with lastDigit + 1.
        if (lastDigit < 9) {
            q.push(curr * 10 + lastDigit + 1);
        }
    }

    return res;
}

// Driver Code
let n = 20;
let res = absDifOne(n);
console.log("[" + res.join(", ") + "]");

Output
[10, 12]

Time Complexity: O(k), where k is the total number of stepping numbers generated that are less than or equal to n. Each generated stepping number is processed exactly once.
Space Complexity: O(k)

[Alternative Approach] Using DFS / Backtracking - O(k log k) Time and O(d) Space

The idea is to recursively generate only the valid numbers instead of checking every number. Start DFS from every one-digit number (1 to 9). For a number ending with digit d, recursively append d - 1 and d + 1 whenever they are valid digits. After generating all valid numbers, sort them to get the required increasing order.

Working of Approach:

  • Start DFS from each digit from 1 to 9.
  • If the current number is greater than n, stop that recursive path.
  • If the current number has at least two digits, store it.
  • Recursively generate the next numbers by appending lastDigit - 1 and lastDigit + 1.
  • Sort the generated numbers and return the result.
C++
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

// DFS function to generate valid numbers.
void dfs(long long curr, int n, vector<int> &res)
{

    // Stop if number exceeds n.
    if (curr > n)
        return;

    // Store valid numbers having at least two digits.
    if (curr >= 10)
        res.push_back(curr);

    int lastDigit = curr % 10;

    // Generate the next number with lastDigit - 1.
    if (lastDigit > 0)
        dfs(curr * 10 + lastDigit - 1, n, res);

    // Generate the next number with lastDigit + 1.
    if (lastDigit < 9)
        dfs(curr * 10 + lastDigit + 1, n, res);
}

vector<int> absDifOne(int n)
{

    vector<int> res;

    // Start DFS from every one-digit number.
    for (int i = 1; i <= 9; i++)
        dfs(i, n, res);

    // Sort to get increasing order.
    sort(res.begin(), res.end());

    return res;
}

int main()
{

    int n = 20;

    vector<int> res = absDifOne(n);

    cout << "[";

    for (int i = 0; i < res.size(); i++)
    {
        cout << res[i];

        if (i + 1 < res.size())
            cout << ", ";
    }

    cout << "]";

    return 0;
}
Java
import java.util.ArrayList;
import java.util.Collections;

public class GFG {
    // DFS function to generate valid numbers.
    private static void dfs(long curr, int n,
                            ArrayList<Integer> res)
    {
        // Stop if number exceeds n.
        if (curr > n)
            return;

        // Store valid numbers having at least two digits.
        if (curr >= 10)
            res.add((int)curr);

        int lastDigit = (int)(curr % 10);

        // Generate the next number with lastDigit - 1.
        if (lastDigit > 0)
            dfs(curr * 10 + lastDigit - 1, n, res);

        // Generate the next number with lastDigit + 1.
        if (lastDigit < 9)
            dfs(curr * 10 + lastDigit + 1, n, res);
    }

    public static ArrayList<Integer> absDifOne(int n)
    {
        ArrayList<Integer> res = new ArrayList<>();

        // Start DFS from every one-digit number.
        for (int i = 1; i <= 9; i++)
            dfs(i, n, res);

        // Sort to get increasing order.
        Collections.sort(res);

        return res;
    }

    public static void main(String[] args)
    {
        int n = 20;
        ArrayList<Integer> res = absDifOne(n);
        System.out.print("[");
        for (int i = 0; i < res.size(); i++) {
            System.out.print(res.get(i));
            if (i + 1 < res.size())
                System.out.print(", ");
        }
        System.out.print("]");
    }
}
Python
def dfs(curr, n, res):
    # Stop if number exceeds n.
    if curr > n:
        return

    # Store valid numbers having at least two digits.
    if curr >= 10:
        res.append(int(curr))

    lastDigit = curr % 10

    # Generate the next number with lastDigit - 1.
    if lastDigit > 0:
        dfs(curr * 10 + lastDigit - 1, n, res)

    # Generate the next number with lastDigit + 1.
    if lastDigit < 9:
        dfs(curr * 10 + lastDigit + 1, n, res)


def absDifOne(n):
    res = []

    # Start DFS from every one-digit number.
    for i in range(1, 10):
        dfs(i, n, res)

    # Sort to get increasing order.
    res.sort()

    return res


if __name__ == '__main__':
    n = 20
    res = absDifOne(n)
    print('[', end='')
    for i in range(len(res)):
        print(res[i], end='' if i == len(res) - 1 else ', ')
    print(']')
C#
using System;
using System.Collections.Generic;
using System.Linq;

public class GFG {
    // DFS function to generate valid numbers.
    private static void dfs(long curr, int n, List<int> res)
    {
        // Stop if number exceeds n.
        if (curr > n)
            return;

        // Store valid numbers having at least two digits.
        if (curr >= 10)
            res.Add((int)curr);

        int lastDigit = (int)(curr % 10);

        // Generate the next number with lastDigit - 1.
        if (lastDigit > 0)
            dfs(curr * 10 + lastDigit - 1, n, res);

        // Generate the next number with lastDigit + 1.
        if (lastDigit < 9)
            dfs(curr * 10 + lastDigit + 1, n, res);
    }

    public static List<int> absDifOne(int n)
    {
        List<int> res = new List<int>();

        // Start DFS from every one-digit number.
        for (int i = 1; i <= 9; i++)
            dfs(i, n, res);

        // Sort to get increasing order.
        res.Sort();

        return res;
    }

    public static void Main()
    {
        int n = 20;
        List<int> res = absDifOne(n);
        Console.Write('[');
        for (int i = 0; i < res.Count; i++) {
            Console.Write(res[i]);
            if (i + 1 < res.Count)
                Console.Write(", ");
        }
        Console.Write(']');
    }
}
JavaScript
// DFS function to generate valid numbers.
function dfs(curr, n, res)
{

    // Stop if number exceeds n.
    if (curr > n)
        return;

    // Store valid numbers having at least two digits.
    if (curr >= 10)
        res.push(curr);

    let lastDigit = curr % 10;

    // Generate the next number with lastDigit - 1.
    if (lastDigit > 0)
        dfs(curr * 10 + lastDigit - 1, n, res);

    // Generate the next number with lastDigit + 1.
    if (lastDigit < 9)
        dfs(curr * 10 + lastDigit + 1, n, res);
}

function absDifOne(n)
{

    let res = [];

    // Start DFS from every one-digit number.
    for (let i = 1; i <= 9; i++)
        dfs(i, n, res);

    // Sort to get increasing order.
    res.sort((a, b) => a - b);

    return res;
}

// Driver code
let n = 20;
let res = absDifOne(n);
console.log("[" + res.join(", ") + "]");

Output
[10, 12]

Time Complexity: O(k + k log k) = O(k log k), where k is the number of valid numbers generated.
Space Complexity: O(d) for recursion stack (d = maximum number of digits).

Comment