Number of n digit stepping numbers - space optimized solution


In this article, we will learn about stepping numbers. We will find the possible number of n digit numbers which are also stepping numbers using several C++ techniques. We will also discuss about the most space optimized solution.

Let’s first discuss about stepping numbers. These are such numbers which have adjacent digits in such a way that they all have a difference of 1. For example, 321- each of the adjacent digits (3, 2, 1) have a difference of 1 consecutively.

Here, we will be given the value of N and then we have to find the count of all N digit stepping numbers.

Input Output Scenarios

We are given N. The number of N digit stepping numbers is the output.

Input: N = 3
Output: 32
Input: N = 4
Output: 61

For N = 3, possible numbers which are stepping numbers are 32. These numbers are 101, 121, 123, 210, 212, 232, 234, 321 and so on.

Using Iteration

We will iterate through all the N digit numbers and check whether they are stepping or not.

  • First, we create a function named steppingNumber which is used to check whether a number is stepping or not. It is a Boolean function, so it returns true or false.

  • In this function, we convert the number to a string using to_string(). Then, we iterate through all the digits and find the difference between each digit. If the difference is not 1, then it is false. Otherwise, the result is true.

  • Next, we create the function to count the stepping numbers. In this function, we iterate from first N digit number to last N digit number. For each number, we apply the steppingNumber function. If the function returns true, the variable count is increased by 1.

Example

Let us see an example −

#include <iostream>
#include <cmath>
using namespace std;
bool steppingNumber(int i) {
   string numStr = to_string(i);
   for (int j = 1; j < numStr.length(); j++) {
      int diff = abs(numStr[j] - numStr[j - 1]);
      if (diff != 1) {
         return false;
      }
   }
   return true;
}
int possibleNumbers(int N) {
   int begin = pow(10, N - 1);
   int end = pow(10, N) - 1;
   int count = 0;
   for (int i = begin; i <= end; i++) {
      if (steppingNumber(i)) {
         count++;
      }
   }
   return count;
}
int main() {
   int N = 3;
   cout << "Number of " << N << " digit stepping numbers are " <<
   possibleNumbers(N);
   return 0;
}

Output

Number of 3 digit stepping numbers are 32

Note − This approach is very simple and is not an efficient one. It provides redundant calculations and more time consuming.

Using Space Optimized Approach

Here, we use the concept that in a stepping number each digit will be one greater than or one less than the previous digit.

  • We have two arrays which stores the count of N-digit stepping numbers as well as (N – 1) digit stepping numbers.

  • We run the loop from 2 to N. Within this loop, we run two for loops each from 0 to 9 (because digits can be within 0 – 9). For each digit, we update the value of previousCount array using the values of currentCount array.

  • If (k > 0), we add the value of previousCount[k – 1] to currentCount array. This is because adding one to the first digit of (N – 1)th digit if the first digit is equal to (k – 1) gives the N digit stepping number.

  • If (k < 9), we add the value of previousCount[k + 1] to currentCount array. This is because adding one to the first digit of (N – 1)th digit if the first digit is equal to (k + 1) gives the N digit stepping number.

  • Next, we add the sum of the values of the array currentCount.

Example

Following is an example −

#include <iostream>
using namespace std;
int possibleNumbers(int N) {
   int previousCount[10] = {0};
   int currentCount[10] = {1, 1, 1, 1, 1, 1, 1 ,1, 1, 1};
   for (int j = 2; j <= N; ++j) {
      for (int k = 0; k <= 9; ++k) {
         previousCount[k] = currentCount[k];
         currentCount[k] = 0;
      }
      for (int k = 0; k <= 9; ++k) {
         if (k > 0)
         currentCount[k] += previousCount[k - 1];
         if (k < 9)
         currentCount[k] += previousCount[k + 1];
      }
   }
   int count = 0;
   for (int k = 1; k <= 9; ++k) {
      count += currentCount[k];
   }
   return count;
}
int main() {
   int N = 5;
   cout << "Number of " << N << " digit stepping numbers are " <<
   possibleNumbers(N);
   return 0;
}

Output

Number of 5 digit stepping numbers are 116

Using Dynamic Approach

We will use single 1D array to store the computations instead of two 1D arrays (like in the previous approach).

Example

#include <iostream>
#include <vector>
using namespace std;
long long possibleNumbers(int N){
   vector<long long> dp(10, 1);
   if (N == 1)
   return 10;
   for (int i = 2; i <= N; i++) {
      vector<long long> new_dp(10, 0);
      new_dp[0] = dp[1];
      new_dp[9] = dp[8];
      for (int j = 1; j <= 8; j++)
      new_dp[j] = dp[j - 1] + dp[j + 1];
      dp = new_dp;
   }
	long long totalCount = 0;
	for (int j = 1; j <= 9; j++)
	totalCount += dp[j];
	return totalCount;
}
int main(){
   int N = 4;
   cout << "Number of " << N << " digit stepping numbers are " <<
   possibleNumbers(N);
   return 0;
}

Output

Number of 4 digit stepping numbers are 61

Conclusion

We have discussed about different ways to find the count of N-digit stepping numbers. The first approach is a simple one using the iteration. The second approach uses two 1D arrays to store the computations and is a space optimized method. In the third approach, we use single 1D array instead of two such arrays which makes the code more efficient.

Updated on: 05-Jan-2024

33 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements