0
votes

A number is called a stepping number if all adjacent digits in the number have an absolute difference of 1.

Examples of stepping numbers :- 0,1,2,3,4,5,6,7,8,9,10,12,21,23,...

I have to generate stepping numbers upto a given number N. The numbers generated should be in order.

I used the simple method of moving over all the numbers upto N and checking if it is stepping number or not. My teacher told me it is brute force and will take more time. Now, I have to optimize my approach.

Any suggestions.

2
Have you tried using BFS? Store the starting stepping numbers first in a queue. Pop them and add new stepping numbers. See the link in my answer.Adarsh Anurag
@AdarshAnurag Depth First Search (DFS) would work just as well, and is simpler to implement.john
but using DFS, numbers cannot be generated in ascending order.Adarsh Anurag
@AdarshAnurag True, but I see no requirement to provide the numbers in ascending order.john
@AdarshAnurag, Thank you for help. I never knew BFS and DFS can be applied here.user11799835

2 Answers

4
votes

Stepping numbers can be generated using Breadth First Search like approach.

Example to find all the stepping numbers from 0 to N

-> 0 is a stepping Number and it is in the range so display it. -> 1 is a Stepping Number, find neighbors of 1 i.e., 10 and 12 and push them into the queue

How to get 10 and 12?

Here U is 1 and last Digit is also 1

V = 10 + 0 = 10 ( Adding lastDigit - 1 )

V = 10 + 2 = 12 ( Adding lastDigit + 1 )

Then do the same for 10 and 12 this will result into 101, 123, 121 but these Numbers are out of range. Now any number transformed from 10 and 12 will result into a number greater than 21 so no need to explore their neighbors.

-> 2 is a Stepping Number, find neighbors of 2 i.e. 21, 23. -> generate stepping numbers till N.

The other stepping numbers will be 3, 4, 5, 6, 7, 8, 9.

C++ code to do generate stepping numbers in a given range:

#include<bits/stdc++.h> 
using namespace std; 

// Prints all stepping numbers reachable from num 
// and in range [n, m] 
void bfs(int n, int m) 
{ 
    // Queue will contain all the stepping Numbers 
    queue<int> q; 

    for (int i = 0 ; i <= 9 ; i++) 
        q.push(i);

    while (!q.empty()) 
    { 
        // Get the front element and pop from the queue 
        int stepNum = q.front(); 
        q.pop(); 

        // If the Stepping Number is in the range 
        // [n, m] then display 
        if (stepNum <= m && stepNum >= n) 
            cout << stepNum << " "; 

        // If Stepping Number is 0 or greater than m, 
        // need to explore the neighbors 
        if (stepNum == 0 || stepNum > m) 
            continue; 

        // Get the last digit of the currently visited 
        // Stepping Number 
        int lastDigit = stepNum % 10; 

        // There can be 2 cases either digit to be 
        // appended is lastDigit + 1 or lastDigit - 1 
        int stepNumA = stepNum * 10 + (lastDigit- 1); 
        int stepNumB = stepNum * 10 + (lastDigit + 1); 

        // If lastDigit is 0 then only possible digit 
        // after 0 can be 1 for a Stepping Number 
        if (lastDigit == 0) 
            q.push(stepNumB); 

        //If lastDigit is 9 then only possible 
        //digit after 9 can be 8 for a Stepping 
        //Number 
        else if (lastDigit == 9) 
            q.push(stepNumA); 

        else
        { 
            q.push(stepNumA); 
            q.push(stepNumB); 
        } 
    } 
}  

//Driver program to test above function 
int main() 
{ 
    int n = 0, m = 99; 

    // Display Stepping Numbers in the 
    // range [n,m] 
    bfs(n,m); 
    return 0; 
} 

Visit this link. The mentioned link has both BFS and DFS approach. It will provide you with explaination and code in different languages for the above problem.

2
votes

We also can use simple rules to move to the next stepping number and generate them in order to avoid storing "parents".

C.f. OEIS sequence

#include <iostream>

int next_stepping(int n) {
    int left = n / 10;
    if (left == 0)
        return (n + 1);   // 6=>7

    int last = n % 10;
    int leftlast = left % 10;
    if (leftlast - last == 1 & last < 8)
        return (n + 2);   // 32=>34

    int nxt = next_stepping(left);
    int nxtlast = nxt % 10;
    if (nxtlast == 0)
        return (nxt * 10 + 1);  // to get 101

    return (nxt * 10 + nxtlast - 1);   //to get 121
}

int main()
{
    int t = 0;
    for (int i = 1; i < 126; i++, t = next_stepping(t)) {
        std::cout << t << "\t";
        if (i % 10 == 0)
            std::cout << "\n";
    }
}

0       1       2       3       4       5       6       7       8       9
10      12      21      23      32      34      43      45      54      56
65      67      76      78      87      89      98      101     121     123
210     212     232     234     321     323     343     345     432     434
454     456     543     545     565     567     654     656     676     678
765     767     787     789     876     878     898     987     989     1010
1012    1210    1212    1232    1234    2101    2121    2123    2321    2323
2343    2345    3210    3212    3232    3234    3432    3434    3454    3456
4321    4323    4343    4345    4543    4545    4565    4567    5432    5434
5454    5456    5654    5656    5676    5678    6543    6545    6565    6567
6765    6767    6787    6789    7654    7656    7676    7678    7876    7878
7898    8765    8767    8787    8789    8987    8989    9876    9878    9898
10101   10121   10123   12101   12121