Given a range
Examples:
Input : 10 12 Output : 2 Explanation : In the given range 10 and 12 have no repeated digit where as 11 has repeated digit. Input : 1 100 Output : 90
Brute Force We will traverse through each element in the given range and count the number of digits which do not have repeated digits.
// C++ implementation of brute // force solution. #include <bits/stdc++.h> using namespace std;
// Function to check if the given // number has repeated digit or not int repeated_digit( int n)
{ unordered_set< int > s;
// Traversing through each digit
while (n != 0)
{
int d = n % 10;
// if the digit is present
// more than once in the
// number
if (s.find(d) != s.end())
{
// return 0 if the number
// has repeated digit
return 0;
}
s.insert(d);
n = n / 10;
}
// return 1 if the number has
// no repeated digit
return 1;
} // Function to find total number // in the given range which has // no repeated digit int calculate( int L, int R)
{ int answer = 0;
// Traversing through the range
for ( int i = L; i < R + 1; ++i)
{
// Add 1 to the answer if i has
// no repeated digit else 0
answer = answer + repeated_digit(i);
}
return answer ;
} // Driver Code int main()
{ int L = 1, R = 100;
// Calling the calculate
cout << calculate(L, R);
return 0;
} // This code is contributed by // Sanjit_Prasad |
// Java implementation of brute // force solution. import java.util.LinkedHashSet;
class GFG
{ // Function to check if the given // number has repeated digit or not static int repeated_digit( int n)
{ LinkedHashSet<Integer> s = new LinkedHashSet<>();
// Traversing through each digit
while (n != 0 )
{
int d = n % 10 ;
// if the digit is present
// more than once in the
// number
if (s.contains(d))
{
// return 0 if the number
// has repeated digit
return 0 ;
}
s.add(d);
n = n / 10 ;
}
// return 1 if the number has
// no repeated digit
return 1 ;
} // Function to find total number // in the given range which has // no repeated digit static int calculate( int L, int R)
{ int answer = 0 ;
// Traversing through the range
for ( int i = L; i < R + 1 ; ++i)
{
// Add 1 to the answer if i has
// no repeated digit else 0
answer = answer + repeated_digit(i);
}
return answer;
} // Driver Code public static void main(String[] args)
{ int L = 1 , R = 100 ;
// Calling the calculate
System.out.println(calculate(L, R));
} } // This code is contributed by RAJPUT-JI |
# Python implementation of brute # force solution. # Function to check if the given # number has repeated digit or not def repeated_digit(n):
a = []
# Traversing through each digit
while n ! = 0 :
d = n % 10
# if the digit is present
# more than once in the
# number
if d in a:
# return 0 if the number
# has repeated digit
return 0
a.append(d)
n = n / / 10
# return 1 if the number has no
# repeated digit
return 1
# Function to find total number # in the given range which has # no repeated digit def calculate(L,R):
answer = 0
# Traversing through the range
for i in range (L,R + 1 ):
# Add 1 to the answer if i has
# no repeated digit else 0
answer = answer + repeated_digit(i)
# return answer
return answer
# Driver's Code L = 1
R = 100
# Calling the calculate print (calculate(L, R))
|
// C# implementation of brute // force solution. using System;
using System.Collections.Generic;
class GFG
{ // Function to check if the given // number has repeated digit or not static int repeated_digit( int n)
{ var s = new HashSet< int >();
// Traversing through each digit
while (n != 0)
{
int d = n % 10;
// if the digit is present
// more than once in the
// number
if (s.Contains(d))
{
// return 0 if the number
// has repeated digit
return 0;
}
s.Add(d);
n = n / 10;
}
// return 1 if the number has
// no repeated digit
return 1;
} // Function to find total number // in the given range which has // no repeated digit static int calculate( int L, int R)
{ int answer = 0;
// Traversing through the range
for ( int i = L; i < R + 1; ++i)
{
// Add 1 to the answer if i has
// no repeated digit else 0
answer = answer + repeated_digit(i);
}
return answer;
} // Driver Code public static void Main(String[] args)
{ int L = 1, R = 100;
// Calling the calculate
Console.WriteLine(calculate(L, R));
} } // This code is contributed by RAJPUT-JI |
<?php // PHP implementation of // brute force solution. // Function to check if // the given number has // repeated digit or not function repeated_digit( $n )
{ $c = 10;
$a = array_fill (0, $c , 0);
// Traversing through
// each digit
while ( $n > 0)
{
$d = $n % 10;
// if the digit is present
// more than once in the
// number
if ( $a [ $d ] > 0)
{
// return 0 if the number
// has repeated digit
return 0;
}
$a [ $d ]++;
$n = (int)( $n / 10);
}
// return 1 if the number
// has no repeated digit
return 1;
} // Function to find total // number in the given range // which has no repeated digit function calculate( $L , $R )
{ $answer = 0;
// Traversing through
// the range
for ( $i = $L ; $i <= $R ; $i ++)
{
// Add 1 to the answer if
// i has no repeated digit
// else 0
$answer += repeated_digit( $i );
}
// return answer
return $answer ;
} // Driver Code $L = 1;
$R = 100;
// Calling the calculate echo calculate( $L , $R );
// This code is contributed by mits ?> |
// JS implementation of brute // force solution. // Function to check if the given // number has repeated digit or not function repeated_digit(n)
{ let s = new Set();
// Traversing through each digit
while (n != 0)
{
let d = n % 10;
// if the digit is present
// more than once in the
// number
if (s.has(d))
{
// return 0 if the number
// has repeated digit
return 0;
}
s.add(d);
n = Math.floor(n / 10);
}
// return 1 if the number has
// no repeated digit
return 1;
} // Function to find total number // in the given range which has // no repeated digit function calculate(L, R)
{ let answer = 0;
// Traversing through the range
for ( var i = L; i < R + 1; ++i)
{
// Add 1 to the answer if i has
// no repeated digit else 0
answer = answer + repeated_digit(i);
}
return answer ;
} // Driver Code let L = 1, R = 100; // Calling the calculate console.log(calculate(L, R)) // This code is contributed by // phasing17 |
Output
90
This method will answer each query in O( N ) time.
Auxiliary Space: O(log(N))
Efficient Approach
We will calculate a prefix array of the numbers which have no repeated digit.
Below is the implementation of above idea.
// C++ implementation of above idea #include <bits/stdc++.h> using namespace std;
// Maximum int MAX = 1000;
// Prefix Array vector< int > Prefix = {0};
// Function to check if the given // number has repeated digit or not int repeated_digit( int n)
{ unordered_set< int > a;
int d;
// Traversing through each digit
while (n != 0)
{
d = n % 10;
// if the digit is present
// more than once in the
// number
if (a.find(d) != a.end())
// return 0 if the number
// has repeated digit
return 0;
a.insert(d);
n = n / 10;
}
// return 1 if the number has no
// repeated digit
return 1;
} // Function to pre calculate // the Prefix array void pre_calculation( int MAX)
{ Prefix.push_back(repeated_digit(1));
// Traversing through the numbers
// from 2 to MAX
for ( int i = 2; i < MAX + 1; i++)
// Generating the Prefix array
Prefix.push_back(repeated_digit(i) + Prefix[i-1]);
} // Calculate Function int calculate( int L, int R)
{ // Answer
return Prefix[R] - Prefix[L-1];
} // Driver code int main()
{ int L = 1, R = 100;
// Pre-calculating the Prefix array.
pre_calculation(MAX);
// Calling the calculate function
// to find the total number of number
// which has no repeated digit
cout << calculate(L, R) << endl;
return 0;
} // This code is contributed by Rituraj Jain |
// Java implementation of above idea import java.util.*;
class GFG
{ // Maximum
static int MAX = 100 ;
// Prefix Array
static Vector<Integer> Prefix = new Vector<>();
// Function to check if the given
// number has repeated digit or not
static int repeated_digit( int n)
{
HashSet<Integer> a = new HashSet<>();
int d;
// Traversing through each digit
while (n != 0 )
{
d = n % 10 ;
// if the digit is present
// more than once in the
// number
if (a.contains(d))
// return 0 if the number
// has repeated digit
return 0 ;
a.add(d);
n /= 10 ;
}
// return 1 if the number has no
// repeated digit
return 1 ;
}
// Function to pre calculate
// the Prefix array
static void pre_calculations()
{
Prefix.add( 0 );
Prefix.add(repeated_digit( 1 ));
// Traversing through the numbers
// from 2 to MAX
for ( int i = 2 ; i < MAX + 1 ; i++)
// Generating the Prefix array
Prefix.add(repeated_digit(i) + Prefix.elementAt(i - 1 ));
}
// Calculate Function
static int calculate( int L, int R)
{
// Answer
return Prefix.elementAt(R) - Prefix.elementAt(L - 1 );
}
// Driver Code
public static void main(String[] args)
{
int L = 1 , R = 100 ;
// Pre-calculating the Prefix array.
pre_calculations();
// Calling the calculate function
// to find the total number of number
// which has no repeated digit
System.out.println(calculate(L, R));
}
} // This code is contributed by // sanjeev2552 |
# Python implementation of # above idea # Prefix Array Prefix = [ 0 ]
# Function to check if # the given number has # repeated digit or not def repeated_digit(n):
a = []
# Traversing through each digit
while n ! = 0 :
d = n % 10
# if the digit is present
# more than once in the
# number
if d in a:
# return 0 if the number
# has repeated digit
return 0
a.append(d)
n = n / / 10
# return 1 if the number has no
# repeated digit
return 1
# Function to pre calculate # the Prefix array def pre_calculation( MAX ):
# To use to global Prefix array
global Prefix
Prefix.append(repeated_digit( 1 ))
# Traversing through the numbers
# from 2 to MAX
for i in range ( 2 , MAX + 1 ):
# Generating the Prefix array
Prefix.append( repeated_digit(i) +
Prefix[i - 1 ] )
# Calculate Function def calculate(L,R):
# Answer
return Prefix[R] - Prefix[L - 1 ]
# Driver Code # Maximum MAX = 1000
# Pre-calculating the Prefix array. pre_calculation( MAX )
# Range L = 1
R = 100
# Calling the calculate function # to find the total number of number # which has no repeated digit print (calculate(L, R))
|
// C# implementation of above idea using System;
using System.Collections.Generic;
class GFG
{ // Maximum
static int MAX = 100;
// Prefix Array
static List< int > Prefix = new List< int >();
// Function to check if the given
// number has repeated digit or not
static int repeated_digit( int n)
{
HashSet< int > a = new HashSet< int >();
int d;
// Traversing through each digit
while (n != 0)
{
d = n % 10;
// if the digit is present
// more than once in the
// number
if (a.Contains(d))
// return 0 if the number
// has repeated digit
return 0;
a.Add(d);
n /= 10;
}
// return 1 if the number has no
// repeated digit
return 1;
}
// Function to pre calculate
// the Prefix array
static void pre_calculations()
{
Prefix.Add(0);
Prefix.Add(repeated_digit(1));
// Traversing through the numbers
// from 2 to MAX
for ( int i = 2; i < MAX + 1; i++)
// Generating the Prefix array
Prefix.Add(repeated_digit(i) +
Prefix[i - 1]);
}
// Calculate Function
static int calculate( int L, int R)
{
// Answer
return Prefix[R] - Prefix[L - 1];
}
// Driver Code
public static void Main(String[] args)
{
int L = 1, R = 100;
// Pre-calculating the Prefix array.
pre_calculations();
// Calling the calculate function
// to find the total number of number
// which has no repeated digit
Console.WriteLine(calculate(L, R));
}
} // This code is contributed by 29AjayKumar |
<script> // JavaScript implementation of brute
// force solution. // Function to check if the given // number has repeated digit or not function repeated_digit(n){
const s = new Set();
// Traversing through each digit
while (n != 0){
let d = n % 10;
// if the digit is present
// more than once in the
// number
if (s.has(d)){
// return 0 if the number
// has repeated digit
return 0;
}
s.add(d);
n = Math.floor(n / 10);
}
// return 1 if the number has
// no repeated digit
return 1;
} // Function to find total number // in the given range which has // no repeated digit function calculate(L, R){
let answer = 0;
// Traversing through the range
for (let i = L; i < R + 1; ++i){
// Add 1 to the answer if i has
// no repeated digit else 0
answer = answer + repeated_digit(i);
}
return answer ;
} // Driver Code { let L = 1, R = 100;
// Calling the calculate
console.log(calculate(L, R));
} // This code is contributed by Gautam goel (gautamgoel962) </script> |
Output
90
Efficient Approach: The above approach can be optimized based on the following idea:
Dynamic programming can be used to solve this problem
- dp[i][j][k][l] represents numbers in the range with i’th position to be filled, j represents tight condition, k represents bitmask set for each digit from 0 to 9 and l represents whether previously non zero digit number taken or not.
- It can be observed that the recursive function is called exponential times. That means that some states are called repeatedly.
So the idea is to store the value of each state. This can be done using by store the value of a state and whenever the function is called, return the stored value without computing again.
- First answer will be calculated for 0 to A – 1 and then calculated for 0 to B then latter one is subtracted with prior one to get answer for range [L, R]
Follow the steps below to solve the problem:
- Create a recursive function that takes four parameters i representing the position to be filled, j representing the tight condition, k representing bitmask and l representing whether previously non zero digit taken or not.
- Call the recursive function for choosing all digits from 0 to 9 apart from N.
- Base case if N size digit formed return 1;
- Create a 2d array dp[N][2][M][2] initially filled with -1.
- If the answer for a particular state is computed then save it in dp[i][j][k][l].
- If the answer for a particular state is already computed then just return dp[i][j][k][l].
Below is the implementation of the above approach:
// C++ code to implement the approach #include <bits/stdc++.h> using namespace std;
// DP table initialized with -1 int dp[11][2][(1LL << 10) - 1][2];
// Recursive Function to find numbers // in the range L to R such that its // digits are distinct int recur( int i, int j, int k, int l, string a)
{ // Base case
if (i == a.size()) {
return 1;
}
// If answer for current state is already
// calculated then just return dp[i][j][k]
if (dp[i][j][k][l] != -1)
return dp[i][j][k][l];
// Answer initialized with zero
int ans = 0;
// Tight condition true
if (j == 1) {
// Iterating from 0 to max value of
// tight condition
for ( int digit = 0; digit <= 9; digit++) {
// mask for digit
int mask = (1 << digit);
// if that digit is available to use
if (mask & k) {
// calling recursive function for max digit
// taken and retaining tight condition
if (digit == (( int )a[i] - 48)) {
ans += recur(i + 1, 1, k - (1 << digit),
1, a);
}
// calling recursive function for zero
// and dropping tight condition
else if (digit == 0) {
ans += recur(i + 1, 0, k, 0, a);
}
// calling recursive function for number
// less than max and dropping condition
else if (digit < (( int )a[i] - 48)) {
ans += recur(i + 1, 0, k - (1 << digit),
1, a);
}
}
}
}
// Tight condition false
else {
// Iterating for all digits
for ( int digit = 0; digit <= 9; digit++) {
int mask = (1 << digit);
if (mask & k) {
// calling recursive function for
// not taking anything
if (digit == 0 and l == 0)
ans += recur(i + 1, 0, k, 0, a);
// calling recursive function for
// taking zero
else if (digit == 0 and l == 1)
ans += recur(i + 1, 0, k - (1 << digit),
1, a);
// calling recursive function for taking
// digits from 1 to 9
else
ans += recur(i + 1, 0, k - (1 << digit),
1, a);
}
}
}
// Save and return dp value
return dp[i][j][k][l] = ans;
} // Function to find numbers // in the range L to R such that its // digits are distinct int countInRange( int A, int B)
{ // Initializing dp array with - 1
memset (dp, -1, sizeof (dp));
A--;
string L = to_string(A), R = to_string(B);
// Numbers with distinct digits in range 0 to L
int ans1 = recur(0, 1, (1 << 10) - 1, 0, L);
// Initializing dp array with - 1
memset (dp, -1, sizeof (dp));
// Numbers with distinct digits in range 0 to R
int ans2 = recur(0, 1, (1 << 10) - 1, 0, R);
// Difference of ans2 and ans1
// will generate answer for required range
return ans2 - ans1;
} // Driver Code int main()
{ // Input 1
int L = 1, R = 100;
// Function Call
cout << countInRange(L, R) << endl;
return 0;
} |
// Java code to implement the approach import java.util.*;
class GFG {
// DP table initialized with -1
static int [][][][] dp = new int [ 11 ][ 2 ][( 1 << 10 )][ 2 ];
// Recursive Function to find numbers
// in the range L to R such that its
// digits are distinct
static int recur( int i, int j, int k, int l, String a)
{
// Base case
if (i == a.length()) {
return 1 ;
}
// If answer for current state is already
// calculated then just return dp[i][j][k]
if (dp[i][j][k][l] != - 1 )
return dp[i][j][k][l];
// Answer initialized with zero
int ans = 0 ;
// Tight condition true
if (j == 1 ) {
// Iterating from 0 to max value of
// tight condition
for ( int digit = 0 ; digit <= 9 ; digit++) {
// mask for digit
int mask = ( 1 << digit);
// if that digit is available to use
if ((mask & k) != 0 ) {
// calling recursive function for max
// digit taken and retaining tight
// condition
if (digit == (( int )a.charAt(i) - 48 )) {
ans += recur(i + 1 , 1 ,
k - ( 1 << digit), 1 ,
a);
}
// calling recursive function for zero
// and dropping tight condition
else if (digit == 0 ) {
ans += recur(i + 1 , 0 , k, 0 , a);
}
// calling recursive function for number
// less than max and dropping condition
else if (digit
< (( int )a.charAt(i) - 48 )) {
ans += recur(i + 1 , 0 ,
k - ( 1 << digit), 1 ,
a);
}
}
}
}
// Tight condition false
else {
// Iterating for all digits
for ( int digit = 0 ; digit <= 9 ; digit++) {
int mask = ( 1 << digit);
if ((mask & k) != 0 ) {
// calling recursive function for
// not taking anything
if (digit == 0 && l == 0 )
ans += recur(i + 1 , 0 , k, 0 , a);
// calling recursive function for
// taking zero
else if (digit == 0 && l == 1 )
ans += recur(i + 1 , 0 ,
k - ( 1 << digit), 1 ,
a);
// calling recursive function for taking
// digits from 1 to 9
else
ans += recur(i + 1 , 0 ,
k - ( 1 << digit), 1 ,
a);
}
}
}
// Save and return dp value
return dp[i][j][k][l] = ans;
}
// Function to find numbers
// in the range L to R such that its
// digits are distinct
static int countInRange( int A, int B)
{
// Initializing dp array with - 1
for ( int [][][] table : dp) {
for ( int [][] row : table) {
for ( int [] innerRow : row) {
Arrays.fill(innerRow, - 1 );
}
}
}
A--;
String L = String.valueOf(A);
String R = String.valueOf(B);
// Numbers with distinct digits in range 0 to L
int ans1 = recur( 0 , 1 , ( 1 << 10 ) - 1 , 0 , L);
// Initializing dp array with - 1
for ( int [][][] table : dp) {
for ( int [][] row : table) {
for ( int [] innerRow : row) {
Arrays.fill(innerRow, - 1 );
}
}
}
// Numbers with distinct digits in range 0 to R
int ans2 = recur( 0 , 1 , ( 1 << 10 ) - 1 , 0 , R);
// Difference of ans2 and ans1
// will generate answer for required range
return ans2 - ans1;
}
// Driver Code
public static void main(String[] args)
{
// Input 1
int L = 1 , R = 100 ;
// Function Call
System.out.println(countInRange(L, R));
}
} |
# Python code to implement the approach # DP table initialized with -1 dp = [[[[ - 1 for l in range ( 2 )] for k in range ( 1 << 10 )] for j in range ( 2 )] for i in range ( 11 )]
def memset(dp):
for i in range ( 11 ):
for j in range ( 2 ):
for k in range ( 1 << 10 ):
for l in range ( 2 ):
dp[i][j][k][l] = - 1
# Recursive Function to find numbers # in the range L to R such that its # digits are distinct def recur(i, j, k, l, a):
# Base case
if i = = len (a):
return 1
# If answer for current state is already
# calculated then just return dp[i][j][k]
if dp[i][j][k][l] ! = - 1 :
return dp[i][j][k][l]
# Answer initialized with zero
ans = 0
# Tight condition true
if j = = 1 :
# Iterating from 0 to max value of
# tight condition
for digit in range ( 10 ):
# mask for digit
mask = ( 1 << digit)
# if that digit is available to use
if mask & k:
# calling recursive function for max digit
# taken and retaining tight condition
if digit = = int (a[i]):
ans + = recur(i + 1 , 1 , k - ( 1 << digit), 1 , a)
# calling recursive function for zero
# and dropping tight condition
elif digit = = 0 :
ans + = recur(i + 1 , 0 , k, 0 , a)
# calling recursive function for number
# less than max and dropping condition
elif digit < int (a[i]):
ans + = recur(i + 1 , 0 , k - ( 1 << digit), 1 , a)
# Tight condition false
else :
# Iterating for all digits
for digit in range ( 10 ):
mask = ( 1 << digit)
if mask & k:
# calling recursive function for
# not taking anything
if digit = = 0 and l = = 0 :
ans + = recur(i + 1 , 0 , k, 0 , a)
# calling recursive function for
# taking zero
elif digit = = 0 and l = = 1 :
ans + = recur(i + 1 , 0 , k - ( 1 << digit), 1 , a)
# calling recursive function for taking
# digits from 1 to 9
else :
ans + = recur(i + 1 , 0 , k - ( 1 << digit), 1 , a)
dp[i][j][k][l] = ans
# Save and return dp value
return ans
# Function to find numbers # in the range L to R such that its # digits are distinct def countInRange(A, B):
# Initializing dp array with - 1
memset(dp)
A - = 1
L = str (A)
R = str (B)
# Numbers with distinct digits in range 0 to
ans1 = recur( 0 , 1 , ( 1 << 10 ) - 1 , 0 , L)
# Initializing dp array with - 1
memset(dp)
# Numbers with distinct digits in range 0 to R
ans2 = recur( 0 , 1 , ( 1 << 10 ) - 1 , 0 , R)
# Difference of ans2 and ans1
# will generate answer for required range
return ans2 - ans1
# Driver Code # Input 1 L = 1
R = 100
# Function Call print (countInRange(L, R))
# This code is contributed by prajwalkandekar123. |
// C# code to implement the approach using System;
public class GFG
{ // DP table initialized with -1
static int [,,,] dp = new int [11, 2, (1 << 10), 2];
// Recursive Function to find numbers
// in the range L to R such that its
// digits are distinct
static int recur( int i, int j, int k, int l, String a)
{
// Base case
if (i == a.Length)
{
return 1;
}
// If answer for current state is already
// calculated then just return dp[i][j][k]
if (dp[i, j, k, l] != -1)
return dp[i, j, k, l];
// Answer initialized with zero
int ans = 0;
// Tight condition true
if (j == 1)
{
// Iterating from 0 to max value of
// tight condition
for ( int digit = 0; digit <= 9; digit++)
{
// mask for digit
int mask = (1 << digit);
// if that digit is available to use
if ((mask & k) != 0)
{
// calling recursive function for max
// digit taken and retaining tight
// condition
if (digit == (( int )a[i] - 48))
{
ans += recur(i + 1, 1,
k - (1 << digit), 1,
a);
}
// calling recursive function for zero
// and dropping tight condition
else if (digit == 0)
{
ans += recur(i + 1, 0, k, 0, a);
}
// calling recursive function for number
// less than max and dropping condition
else if (digit
< (( int )a[i] - 48))
{
ans += recur(i + 1, 0,
k - (1 << digit), 1,
a);
}
}
}
}
// Tight condition false
else
{
// Iterating for all digits
for ( int digit = 0; digit <= 9; digit++)
{
int mask = (1 << digit);
if ((mask & k) != 0)
{
// calling recursive function for
// not taking anything
if (digit == 0 && l == 0)
ans += recur(i + 1, 0, k, 0, a);
// calling recursive function for
// taking zero
else if (digit == 0 && l == 1)
ans += recur(i + 1, 0,
k - (1 << digit), 1,
a);
// calling recursive function for taking
// digits from 1 to 9
else
ans += recur(i + 1, 0,
k - (1 << digit), 1,
a);
}
}
}
// Save and return dp value
return dp[i, j, k, l] = ans;
}
// Function to find numbers
// in the range L to R such that its
// digits are distinct
static int countInRange( int A, int B)
{
// Initializing dp array with - 1
for ( int i = 0; i < dp.GetLength(0); i++)
{
for ( int j = 0; j < dp.GetLength(1); j++)
{
for ( int k = 0; k < dp.GetLength(2); k++)
{
for ( int l = 0; l < dp.GetLength(3); l++)
{
dp[i, j, k, l] = -1;
}
}
}
}
A--;
String L = A.ToString();
String R = B.ToString();
// Numbers with distinct digits in range 0 to L
int ans1 = recur(0, 1, (1 << 10) - 1, 0, L);
// Initializing dp array with - 1
for ( int i = 0; i < dp.GetLength(0); i++)
{
for ( int j = 0; j < dp.GetLength(1); j++)
{
for ( int k = 0; k < dp.GetLength(2); k++)
{
for ( int l = 0; l < dp.GetLength(3); l++)
{
dp[i, j, k, l] = -1;
}
}
}
}
// Numbers with distinct digits in range 0 to R
int ans2 = recur(0, 1, (1 << 10) - 1, 0, R);
// Difference of ans2 and ans1
// will generate answer for required range
return ans2 - ans1;
}
// Driver Code
public static void Main(String[] args)
{
// Input 1
int L = 1, R = 100;
// Function Call
Console.WriteLine(countInRange(L, R));
}
} |
// Javascript code to implement the approach // DP table initialized with -1 //int dp[11][2][(1LL << 10) - 1][2]; let dp= new Array(11);
for (let i=0; i<11; i++)
{ dp[i]= new Array(2);
for (let j=0; j<2; j++)
{
dp[i][j]= new Array(1<<10);
for (let k=0; k<(1<<10); k++)
dp[i][j][k]= new Array(2);
}
} function memset(dp)
{ for (let i=0; i<11; i++)
{
for (let j=0; j<2; j++)
{
for (let k=0; k<(1<<10); k++)
for (let l=0; l<2; l++)
dp[i][j][k][l]=-1;
}
}
} // Recursive Function to find numbers // in the range L to R such that its // digits are distinct function recur(i, j, k, l, a)
{ // Base case
if (i == a.length) {
return 1;
}
// If answer for current state is already
// calculated then just return dp[i][j][k]
if (dp[i][j][k][l] != -1)
return dp[i][j][k][l];
// Answer initialized with zero
let ans = 0;
// Tight condition true
if (j == 1) {
// Iterating from 0 to max value of
// tight condition
for (let digit = 0; digit <= 9; digit++) {
// mask for digit
let mask = (1 << digit);
// if that digit is available to use
if (mask & k) {
// calling recursive function for max digit
// taken and retaining tight condition
if (digit == (parseInt(a[i]))) {
ans += recur(i + 1, 1, k - (1 << digit),
1, a);
}
// calling recursive function for zero
// and dropping tight condition
else if (digit == 0) {
ans += recur(i + 1, 0, k, 0, a);
}
// calling recursive function for number
// less than max and dropping condition
else if (digit < (parseInt(a[i]))) {
ans += recur(i + 1, 0, k - (1 << digit),
1, a);
}
}
}
}
// Tight condition false
else {
// Iterating for all digits
for (let digit = 0; digit <= 9; digit++) {
let mask = (1 << digit);
if (mask & k) {
// calling recursive function for
// not taking anything
if (digit == 0 && l == 0)
ans += recur(i + 1, 0, k, 0, a);
// calling recursive function for
// taking zero
else if (digit == 0 && l == 1)
ans += recur(i + 1, 0, k - (1 << digit),
1, a);
// calling recursive function for taking
// digits from 1 to 9
else
ans += recur(i + 1, 0, k - (1 << digit),
1, a);
}
}
}
// Save and return dp value
return dp[i][j][k][l] = ans;
} // Function to find numbers // in the range L to R such that its // digits are distinct function countInRange(A, B)
{ // Initializing dp array with - 1
memset(dp);
A--;
let L = A.toString(), R = B.toString();
// Numbers with distinct digits in range 0 to L
let ans1 = recur(0, 1, (1 << 10) - 1, 0, L);
// Initializing dp array with - 1
memset(dp);
// Numbers with distinct digits in range 0 to R
let ans2 = recur(0, 1, (1 << 10) - 1, 0, R);
// Difference of ans2 and ans1
// will generate answer for required range
return ans2 - ans1;
} // Driver Code // Input 1
let L = 1, R = 100;
// Function Call
console.log(countInRange(L, R));
|
Output
90
Time Complexity: O(log(R – L) * M)
Auxiliary Space: O(log(R – L) * M)
Where M is the all possible subsets of set containing all digits from 0 to 9 for bitmask M = 1024
Related Articles:
- Introduction to Dynamic Programming – Data Structures and Algorithms Tutorials
- Bitmasking and Dynamic Programming