A number is called as a Jumping Number if all adjacent digits in it differ by 1. The difference between ‘9’ and ‘0’ is not considered as 1.
All single digit numbers are considered as Jumping Numbers. For example 7, 8987 and 4343456 are Jumping numbers but 796 and 89098 are not.
Given a positive number x, print all Jumping Numbers smaller than or equal to x. The numbers can be printed in any order.
Example:
Input: x = 20
Output: 0 1 2 3 4 5 6 7 8 9 10 12
Input: x = 105
Output: 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
Note: Order of output doesn't matter,
i.e. numbers can be printed in any order
One Simple Solution is to traverse all numbers from 0 to x. For every traversed number, check if it is a Jumping number. If yes, then print it. Otherwise ignore it.
C++14
#include <bits/stdc++.h>
using namespace std;
void print_sieve( int & x)
{
int i,temp,digit;
bool check;
for (i=0;i<=x;i++)
{
if (i<10)
{
cout<<i<< " " ;
continue ;
}
check=1;
temp=i;
digit=temp%10;
temp/=10;
while (temp)
{
if ( abs (digit-temp%10)!=1)
{
check=0;
break ;
}
digit=temp%10;
temp/=10;
}
if (check)
cout<<i<< " " ;
}
}
int main()
{
int x=105;
print_sieve(x);
return 0;
}
|
Java
import java.util.*;
import java.lang.*;
import java.io.*;
class GFG
{
public static void print_sieve( int x)
{
int i, temp, digit;
int check;
for (i = 0 ; i <= x; i++)
{
if (i < 10 )
{
System.out.print(i + " " );
continue ;
}
check = 1 ;
temp = i;
digit = temp % 10 ;
temp /= 10 ;
while (temp != 0 )
{
if (Math.abs(digit - temp % 10 ) != 1 )
{
check = 0 ;
break ;
}
digit = temp % 10 ;
temp /= 10 ;
}
if (check != 0 )
System.out.print(i + " " );
}
}
public static void main(String[] args)
{
int x = 105 ;
print_sieve(x);
}
}
|
Python3
def print_sieve(x):
for i in range (x + 1 ):
if (i < 10 ):
print (i, end = " " )
continue
check = 1
temp = i
digit = temp % 10
temp / / = 10
while (temp > 0 ):
if ( abs (digit - temp % 10 ) ! = 1 ):
check = 0
break
digit = temp % 10
temp / / = 10
if (check):
print (i, end = " " )
x = 105
print_sieve(x)
|
C#
using System;
class GFG
{
static void print_sieve( int x)
{
int i, temp, digit;
int check;
for (i = 0; i <= x; i++)
{
if (i < 10)
{
Console.Write(i + " " );
continue ;
}
check = 1;
temp = i;
digit = temp % 10;
temp /= 10;
while (temp != 0)
{
if (Math.Abs(digit - temp % 10) != 1)
{
check = 0;
break ;
}
digit = temp % 10;
temp /= 10;
}
if (check != 0)
Console.Write(i + " " );
}
}
public static void Main()
{
int x = 105;
print_sieve(x);
}
}
|
Javascript
<script>
function print_sieve(x)
{
let i,temp,digit;
let check;
for (i = 0; i <= x; i++)
{
if (i < 10)
{
document.write(i, " " );
continue ;
}
check = 1;
temp = i;
digit = temp % 10;
temp = Math.floor(temp / 10);
while (temp)
{
if (Math.abs(digit - temp % 10) != 1)
{
check = 0;
break ;
}
digit = temp % 10;
temp = Math.floor(temp / 10);
}
if (check)
document.write(i, " " );
}
}
let x = 105;
print_sieve(x);
</script>
|
Output0 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
Time Complexity: O(x)
Auxiliary Space: O(1)
An Efficient Solution can solve this problem in O(k) time where k is number of Jumping Numbers smaller than or equal to x. The idea is use BFS or DFS.
Assume that we have a graph where the starting node is 0 and we need to traverse it from the start node to all the reachable nodes.
With the restrictions given in the graph about the jumping numbers, what do you think should be the restrictions defining the next transitions in the graph.
Lets take a example for input x = 90
Start node = 0
From 0, we can move to 1 2 3 4 5 6 7 8 9
[these are not in our range so we don't add it]
Now from 1, we can move to 12 and 10
From 2, 23 and 21
From 3, 34 and 32
.
.
.
.
.
.
and so on.
Below is BFS based implementation of above idea.
C++
#include <bits/stdc++.h>
using namespace std;
void bfs( int x, int num)
{
queue< int > q;
q.push(num);
while (!q.empty()) {
num = q.front();
q.pop();
if (num <= x) {
cout << num << " " ;
int last_dig = num % 10;
if (last_dig == 0)
q.push((num * 10) + (last_dig + 1));
else if (last_dig == 9)
q.push((num * 10) + (last_dig - 1));
else {
q.push((num * 10) + (last_dig - 1));
q.push((num * 10) + (last_dig + 1));
}
}
}
}
void printJumping( int x)
{
cout << 0 << " " ;
for ( int i = 1; i <= 9 && i <= x; i++)
bfs(x, i);
}
int main()
{
int x = 40;
printJumping(x);
return 0;
}
|
Java
import java.util.*;
import java.lang.*;
import java.io.*;
class GFG {
public void bfs( int x, int num)
{
Queue<Integer> q = new LinkedList<Integer>();
q.add(num);
while (!q.isEmpty()) {
num = q.peek();
q.poll();
if (num <= x) {
System.out.print(num + " " );
int last_digit = num % 10 ;
if (last_digit == 0 ) {
q.add((num * 10 ) + (last_digit + 1 ));
}
else if (last_digit == 9 ) {
q.add((num * 10 ) + (last_digit - 1 ));
}
else {
q.add((num * 10 ) + (last_digit - 1 ));
q.add((num * 10 ) + (last_digit + 1 ));
}
}
}
}
public void printJumping( int x)
{
System.out.print( "0 " );
for ( int i = 1 ; i <= 9 && i <= x; i++) {
this .bfs(x, i);
}
}
public static void main(String[] args) throws IOException
{
int x = 40 ;
GFG obj = new GFG();
obj.printJumping(x);
}
}
|
Python3
class Queue:
def __init__( self ):
self .lst = []
def is_empty( self ):
return self .lst = = []
def enqueue( self , elem):
self .lst.append(elem)
def dequeue( self ):
return self .lst.pop( 0 )
def bfs(x, num):
q = Queue()
q.enqueue(num)
while ( not q.is_empty()):
num = q.dequeue()
if num< = x:
print ( str (num), end = ' ' )
last_dig = num % 10
if last_dig = = 0 :
q.enqueue((num * 10 ) + (last_dig + 1 ))
elif last_dig = = 9 :
q.enqueue((num * 10 ) + (last_dig - 1 ))
else :
q.enqueue((num * 10 ) + (last_dig - 1 ))
q.enqueue((num * 10 ) + (last_dig + 1 ))
def printJumping(x):
print ( str ( 0 ), end = ' ' )
for i in range ( 1 , 10 ):
bfs(x, i)
x = 40
printJumping(x)
|
C#
using System;
using System.Collections.Generic;
class GFG
{
public void bfs( int x, int num)
{
Queue< int > q = new Queue< int >();
q.Enqueue(num);
while (q.Count!=0)
{
num = q.Peek();
q.Dequeue();
if (num <= x)
{
Console.Write(num + " " );
int last_digit = num % 10;
if (last_digit == 0)
{
q.Enqueue((num * 10) + (last_digit + 1));
}
else if (last_digit == 9)
{
q.Enqueue((num * 10) + (last_digit - 1));
}
else
{
q.Enqueue((num * 10) + (last_digit - 1));
q.Enqueue((num * 10) + (last_digit + 1));
}
}
}
}
public void printJumping( int x)
{
Console.Write( "0 " );
for ( int i = 1; i <= 9 && i <= x; i++)
{
this .bfs(x, i);
}
}
public static void Main(String[] args)
{
int x = 40;
GFG obj = new GFG();
obj.printJumping(x);
}
}
|
Javascript
<script>
function bfs(x, num)
{
let q = [];
q.push(num);
while (q.length != 0)
{
num = q.shift();
if (num <= x)
{
document.write(num + " " );
let last_digit = num % 10;
if (last_digit == 0)
{
q.push((num * 10) + (last_digit + 1));
}
else if (last_digit == 9)
{
q.push((num * 10) + (last_digit - 1));
}
else
{
q.push((num * 10) + (last_digit - 1));
q.push((num * 10) + (last_digit + 1));
}
}
}
}
function printJumping(x)
{
document.write( "0 " );
for (let i = 1; i <= 9 && i <= x; i++)
{
bfs(x, i);
}
}
let x = 40;
printJumping(x);
</script>
|
Output0 1 10 12 2 21 23 3 32 34 4 5 6 7 8 9
Time Complexity: O(k) time where k is number of Jumping Numbers smaller than or equal to x
Auxiliary Space: O(1)
Thanks to Gaurav Ahirwar for above solution.
Exercise:
- Change the above solution to use DFS instead of BFS.
- Extend your solution to print all numbers in sorted order instead of any order.
- Further extend the solution to print all numbers in a given range.
DFS based solution:
In the DFS based approach we start building our numbers from single digits , i.e. from 1 – 9. Then we check for next possible digit and if possible we call the dfs for those numbers, increasing the number of digits with each call.
Algorithm:
1. We will start from every possible single digit, i.e. from 1 to 9
2. In the dfs we first write the base case, then
3. We print the current number
4. We get the last digit of current number and
check the possibilities for the next digit.
The next digit can either be last digit + 1 or last digit - 1
5. If the last digit is either 0 or 9 we have only one option for
next number, else both the options are possible.
See C++ implementation of above approach:
C++
#include <bits/stdc++.h>
using namespace std;
#define ll long long
void dfs(ll cnum, const ll& num)
{
if (cnum > num)
return ;
cout << cnum << " " ;
int l_dig = cnum % 10;
ll first = cnum * 10 + l_dig + 1;
ll second = cnum * 10 + l_dig - 1;
if (l_dig == 0)
dfs(first, num);
else if (l_dig == 9)
dfs(second, num);
else
{
dfs(first, num);
dfs(second, num);
}
}
void PrintJumping( long long X)
{
cout << 0 << " " ;
for (ll i = 1; i <= 9; i++) {
dfs(i, X);
}
}
int main()
{
long long X = 40;
PrintJumping(X);
return 0;
}
|
Java
import java.util.*;
class gfg2 {
static void dfs( long cnum, long num)
{
if (cnum > num)
return ;
System.out.print(cnum
+ " " );
int l_dig = ( int )(cnum % 10 );
long first = cnum * 10 + l_dig + 1 ;
long second = cnum * 10 + l_dig - 1 ;
if (l_dig == 0 )
dfs(first, num);
else if (l_dig
== 9 )
dfs(second, num);
else
{
dfs(first, num);
dfs(second, num);
}
}
static void PrintJumping( long X)
{
System.out.print( 0 + " " );
for ( long i = 1L; i <= 9 ; i++) {
dfs(i, X);
}
}
public static void main(String[] args)
{
long X = 40 ;
PrintJumping(X);
}
}
|
Python3
def dfs(cnum, num):
if cnum > num:
return
print (cnum, end = " " )
l_dig = cnum % 10
first = cnum * 10 + l_dig + 1
second = cnum * 10 + l_dig - 1
if l_dig = = 0 :
dfs(first, num)
elif l_dig = = 9 :
dfs(second, num)
else :
dfs(first, num)
dfs(second, num)
def PrintJumping(X):
print ( 0 , end = " " )
for i in range ( 1 , 10 ):
dfs(i, X)
if __name__ = = '__main__' :
X = 40
PrintJumping(X)
|
C#
using System;
class GFG {
static void dfs( long cnum, long num)
{
if (cnum > num)
return ;
Console.Write(cnum
+ " " );
int l_dig = ( int )(cnum % 10);
long first = cnum * 10 + l_dig + 1;
long second = cnum * 10 + l_dig - 1;
if (l_dig == 0)
dfs(first, num);
else if (l_dig
== 9)
dfs(second, num);
else
{
dfs(first, num);
dfs(second, num);
}
}
static void PrintJumping( long X)
{
Console.Write(0 + " " );
for ( long i = 1L; i <= 9; i++) {
dfs(i, X);
}
}
static void Main( string [] args)
{
long X = 40;
PrintJumping(X);
}
}
|
Javascript
function dfs(cnum, num)
{
if (cnum > num)
return ;
console.log(cnum+ " " );
let l_dig = cnum % 10;
let first = cnum * 10 + l_dig + 1;
let second = cnum * 10 + l_dig - 1;
if (l_dig == 0)
dfs(first, num);
else if (l_dig == 9)
dfs(second, num);
else
{
dfs(first, num);
dfs(second, num);
}
}
function PrintJumping(X)
{
console.log(0+ " " );
for (let i = 1; i <= 9; i++) {
dfs(i, X);
}
}
let X = 40;
PrintJumping(X);
|
Output0 1 12 10 2 23 21 3 34 32 4 5 6 7 8 9
Time Complexity: O(k)
Here k is the total number of jumping numbers.
Auxiliary Space: O(len(N))
Here len(N) is the maximum length from all the jumping numbers, the extra space is used due to recursive function call stack.