Count of numbers in the range [L, R] which satisfy the given conditions
Last Updated :
09 May, 2023
Given a range [L, R], the task is to find the count of numbers from this range that satisfy the below conditions:
- All the digit in the number are distinct.
- All the digits are less than or equal to 5.
Examples:
Input: L = 4, R = 13
Output: 5
4, 5, 10, 12 and 13 are the only
valid numbers in the range [4, 13].
Input: L = 100, R = 1000
Output: 100
Approach: The question seems simple if the range is small because in that case, all the numbers from the range can be iterated and checked whether they are valid or not. But since the range could be large, it can be observed all the digits of a valid number has to be distinct and from the range [0, 5] which suggests that the maximum number cannot exceed 543210.
Now instead of checking for every number, the next valid number in the series can be generated from the previously generated numbers. The idea is similar to the approach discussed here.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
#define MAX 543210
vector<string> ans;
bool isValidNum(string x)
{
map< int , int > mp;
for ( int i = 0; i < x.length(); i++) {
if (mp.find(x[i] - '0' ) != mp.end()) {
return false ;
}
else if (x[i] - '0' > 5) {
return false ;
}
else {
mp[x[i] - '0' ] = 1;
}
}
return true ;
}
void generate()
{
queue<string> q;
q.push( "1" );
q.push( "2" );
q.push( "3" );
q.push( "4" );
q.push( "5" );
bool flag = true ;
ans.push_back( "0" );
while (!q.empty()) {
string x = q.front();
q.pop();
if (isValidNum(x)) {
ans.push_back(x);
}
if (x.length() == 6)
continue ;
for ( int i = 0; i <= 5; i++) {
string z = to_string(i);
string temp = x + z;
q.push(temp);
}
}
}
bool comp(string a, string b)
{
if (a.size() == b.size())
return a < b;
else
return a.size() < b.size();
}
int findcount(string l, string r)
{
generate();
int count = 0;
for ( int i = 0; i < ans.size(); i++) {
string a = ans[i];
if (comp(l, a) && comp(a, r)) {
count++;
}
else if (a == l || a == r) {
count++;
}
}
return count;
}
int main()
{
string l = "1" , r = "1000" ;
cout << findcount(l, r);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static int MAX = 543210 ;
static Vector<String> ans = new Vector<String>();
static boolean isValidNum(String x)
{
HashMap<Integer,
Integer> mp = new HashMap<Integer,
Integer>();
for ( int i = 0 ; i < x.length(); i++)
{
if (mp.containsKey(x.charAt(i) - '0' ))
{
return false ;
}
else if (x.charAt(i) - '0' > 5 )
{
return false ;
}
else
{
mp.put(x.charAt(i) - '0' , 1 );
}
}
return true ;
}
static void generate()
{
Queue<String> q = new LinkedList<String>();
q.add( "1" );
q.add( "2" );
q.add( "3" );
q.add( "4" );
q.add( "5" );
boolean flag = true ;
ans.add( "0" );
while (!q.isEmpty())
{
String x = q.peek();
q.remove();
if (isValidNum(x))
{
ans.add(x);
}
if (x.length() == 6 )
continue ;
for ( int i = 0 ; i <= 5 ; i++)
{
String z = String.valueOf(i);
String temp = x + z;
q.add(temp);
}
}
}
static boolean comp(String a, String b)
{
if (a.length()== b.length())
{
int i = a.compareTo(b);
return i < 0 ? true : false ;
}
else
return a.length() < b.length();
}
static int findcount(String l, String r)
{
generate();
int count = 0 ;
for ( int i = 0 ; i < ans.size(); i++)
{
String a = ans.get(i);
if (comp(l, a) && comp(a, r))
{
count++;
}
else if (a == l || a == r)
{
count++;
}
}
return count;
}
public static void main (String[] args)
{
String l = "1" , r = "1000" ;
System.out.println(findcount(l, r));
}
}
|
Python3
from collections import deque
MAX = 543210
ans = []
def isValidNum(x):
mp = dict ()
for i in range ( len (x)):
if ( ord (x[i]) - ord ( '0' ) in mp.keys()):
return False
elif ( ord (x[i]) - ord ( '0' ) > 5 ):
return False
else :
mp[ ord (x[i]) - ord ( '0' )] = 1
return True
def generate():
q = deque()
q.append( "1" )
q.append( "2" )
q.append( "3" )
q.append( "4" )
q.append( "5" )
flag = True
ans.append( "0" )
while ( len (q) > 0 ):
x = q.popleft()
if (isValidNum(x)):
ans.append(x)
if ( len (x) = = 6 ):
continue
for i in range ( 6 ):
z = str (i)
temp = x + z
q.append(temp)
def comp(a, b):
if ( len (a) = = len (b)):
if a < b:
return True
else :
return len (a) < len (b)
def findcount(l, r):
generate()
count = 0
for i in range ( len (ans)):
a = ans[i]
if (comp(l, a) and comp(a, r)):
count + = 1
elif (a = = l or a = = r):
count + = 1
return count
l = "1"
r = "1000"
print (findcount(l, r))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int MAX = 543210;
static List<String> ans = new List<String>();
static bool isValidNum(String x)
{
Dictionary< int , int > mp = new Dictionary< int , int >();
for ( int i = 0; i < x.Length; i++)
{
if (mp.ContainsKey(x[i] - '0' ))
{
return false ;
}
else if (x[i] - '0' > 5)
{
return false ;
}
else
{
mp.Add(x[i] - '0' , 1);
}
}
return true ;
}
static void generate()
{
Queue<String> q = new Queue<String>();
q.Enqueue( "1" );
q.Enqueue( "2" );
q.Enqueue( "3" );
q.Enqueue( "4" );
q.Enqueue( "5" );
bool flag = true ;
ans.Add( "0" );
while (q.Count!=0)
{
String x = q.Peek();
q.Dequeue();
if (isValidNum(x))
{
ans.Add(x);
}
if (x.Length == 6)
continue ;
for ( int i = 0; i <= 5; i++)
{
String z = i.ToString();
String temp = x + z;
q.Enqueue(temp);
}
}
}
static bool comp(String a, String b)
{
if (a.Length == b.Length)
{
int i = a.CompareTo(b);
return i < 0 ? true : false ;
}
else
return a.Length < b.Length;
}
static int findcount(String l, String r)
{
generate();
int count = 0;
for ( int i = 0; i < ans.Count; i++)
{
String a = ans[i];
if (comp(l, a) && comp(a, r))
{
count++;
}
else if (a == l || a == r)
{
count++;
}
}
return count;
}
public static void Main (String[] args)
{
String l = "1" , r = "1000" ;
Console.WriteLine(findcount(l, r));
}
}
|
Javascript
<script>
let MAX = 543210;
let ans = [];
function isValidNum(x)
{
let mp = new Map();
for (let i = 0; i < x.length; i++)
{
if (mp.has(x[i].charCodeAt(0) - '0' .charCodeAt(0)))
{
return false ;
}
else if (x[i].charCodeAt(0) - '0' .charCodeAt(0) > 5)
{
return false ;
}
else
{
mp.set(x[i].charCodeAt(0) - '0' .charCodeAt(0), 1);
}
}
return true ;
}
function generate()
{
let q = [];
q.push( "1" );
q.push( "2" );
q.push( "3" );
q.push( "4" );
q.push( "5" );
let flag = true ;
ans.push( "0" );
while (q.length!=0)
{
let x = q.shift();
if (isValidNum(x))
{
ans.push(x);
}
if (x.length == 6)
continue ;
for (let i = 0; i <= 5; i++)
{
let z = (i).toString();
let temp = x + z;
q.push(temp);
}
}
}
function comp(a,b)
{
if (a.length== b.length)
{
return a < b ? true : false ;
}
else
return a.length < b.length;
}
function findcount(l,r)
{
generate();
let count = 0;
for (let i = 0; i < ans.length; i++)
{
let a = ans[i];
if (comp(l, a) && comp(a, r))
{
count++;
}
else if (a == l || a == r)
{
count++;
}
}
return count;
}
let l = "1" , r = "1000" ;
document.write(findcount(l, r));
</script>
|
Another Approach :
The next valid number in the series can be generated from the previously generated numbers and binary search is used instead of linear search to reduce the time complexity.
C++
#include<bits/stdc++.h>
using namespace std;
bool possible(string x)
{
unordered_map< char , int > mp;
for ( char i : x) {
if (mp.find(i) == mp.end()) {
mp[i] = 1;
} else {
return false ;
}
}
return true ;
}
void total(vector<string> &a)
{
int i = 1;
while (i < a.size())
{
string x = a[i];
i++;
if (x.size() == 5) {
continue ;
}
for ( int j = 0; j <= 5; j++)
{
string z = to_string(j);
if (possible(x + z))
{
a.push_back(x+z);
}
}
}
}
void PrintSolution(vector<string> &a, int l, int r) {
int ans1 = 0, ans2 = 0;
int low = 0, high = a.size()-1;
while (low <= high) {
int mid = (low+high)/2;
if (stoi(a[mid]) == l) {
ans1 = mid;
break ;
} else if (stoi(a[mid]) > l) {
ans1 = mid;
high = mid - 1;
} else {
low = mid + 1;
}
}
low = 0;
high = a.size()-1;
while (low <= high) {
int mid = (low+high)/2;
if (stoi(a[mid]) == r) {
ans2 = mid;
break ;
} else if (stoi(a[mid]) < r) {
ans2 = mid;
low = mid + 1;
} else {
high = mid - 1;
}
}
cout << ans2-ans1+1 << endl;
}
int main() {
vector<string> a = { "0" , "1" , "2" , "3" , "4" , "5" };
total(a);
int l = 1, r = 1000;
PrintSolution(a, l, r);
return 0;
}
|
Java
import java.util.*;
public class UniqueDigits
{
public static boolean possible(String x)
{
HashMap<Character, Integer> d = new HashMap<>();
for ( int i = 0 ; i < x.length(); i++) {
char c = x.charAt(i);
if (!d.containsKey(c)) {
d.put(c, 1 );
} else {
return false ;
}
}
return true ;
}
public static void total(ArrayList<String> a) {
int i = 1 ;
while (i < a.size())
{
String x = a.get(i);
i++;
if (x.length() == 5 ) {
continue ;
}
for ( int j = 0 ; j <= 5 ; j++)
{
String z = Integer.toString(j);
if (possible(x + z))
{
a.add(x + z);
}
}
}
}
public static void printSolution(ArrayList<String> a, int l, int r) {
int ans1 = 0 , ans2 = 0 ;
int low = 0 , high = a.size() - 1 ;
while (low <= high) {
int mid = (low + high) / 2 ;
if (Integer.parseInt(a.get(mid)) == l) {
ans1 = mid;
break ;
}
if (Integer.parseInt(a.get(mid)) > l) {
ans1 = mid;
high = mid - 1 ;
} else {
low = mid + 1 ;
}
}
low = 0 ;
high = a.size() - 1 ;
while (low <= high) {
int mid = (low + high) / 2 ;
if (Integer.parseInt(a.get(mid)) == r) {
ans2 = mid;
break ;
}
if (Integer.parseInt(a.get(mid)) < r) {
ans2 = mid;
low = mid + 1 ;
} else {
high = mid - 1 ;
}
}
System.out.println(ans2 - ans1 + 1 );
}
public static void main(String[] args) {
ArrayList<String> a = new ArrayList<String>(Arrays.asList( "0" , "1" , "2" , "3" , "4" , "5" ));
total(a);
int l = 1 , r = 1000 ;
printSolution(a, l, r);
}
}
|
Python3
def possible(x):
d = {}
for i in x:
if i not in d:
d[i] = 1
else :
return 0
return 1
def total(a):
i = 1
while i < len (a):
x = a[i]
i + = 1
if len (x) = = 6 :
continue
for j in range ( 6 ):
z = str (j)
if possible(x + z):
a.append(x + z)
def PrintSolution(a, l, r):
ans1 = ans2 = 0
low = 0
high = len (a) - 1
while low < = high:
mid = (low + high) / / 2
if int (a[mid]) = = l:
ans1 = mid
break
if int (a[mid]) > l:
ans1 = mid
high = mid - 1
else :
low = mid + 1
low = 0
high = len (a) - 1
while low < = high:
mid = (low + high) / / 2
if int (a[mid]) = = r:
ans2 = mid
break
if int (a[mid]) < r:
ans2 = mid
low = mid + 1
else :
high = mid - 1
print (ans2 - ans1 + 1 )
a = [ '0' , '1' , '2' , '3' , '4' , '5' ]
total(a)
l = 1
r = 1000
PrintSolution(a, l, r)
|
C#
using System;
using System.Collections.Generic;
public class UniqueDigits
{
public static bool Possible( string x)
{
Dictionary< char , int > d = new Dictionary< char , int >();
for ( int i = 0; i < x.Length; i++)
{
char c = x[i];
if (!d.ContainsKey(c))
{
d.Add(c, 1);
}
else
{
return false ;
}
}
return true ;
}
public static void Total(List< string > a)
{
int i = 1;
while (i < a.Count)
{
string x = a[i];
i++;
if (x.Length == 5)
{
continue ;
}
for ( int j = 0; j <= 5; j++)
{
string z = j.ToString();
if (Possible(x + z))
{
a.Add(x + z);
}
}
}
}
public static void PrintSolution(List< string > a, int l, int r)
{
int ans1 = 0, ans2 = 0;
int low = 0, high = a.Count - 1;
while (low <= high)
{
int mid = (low + high) / 2;
if ( int .Parse(a[mid]) == l)
{
ans1 = mid;
break ;
}
if ( int .Parse(a[mid]) > l)
{
ans1 = mid;
high = mid - 1;
}
else
{
low = mid + 1;
}
}
low = 0;
high = a.Count - 1;
while (low <= high)
{
int mid = (low + high) / 2;
if ( int .Parse(a[mid]) == r)
{
ans2 = mid;
break ;
}
if ( int .Parse(a[mid]) < r)
{
ans2 = mid;
low = mid + 1;
}
else
{
high = mid - 1;
}
}
Console.WriteLine(ans2 - ans1 + 1);
}
public static void Main( string [] args)
{
List< string > a = new List< string >( new string [] { "0" , "1" , "2" , "3" , "4" , "5" });
Total(a);
int l = 1, r = 1000;
PrintSolution(a, l, r);
}
}
|
Javascript
function possible(x) {
var d = {};
for ( var i = 0; i < x.length; i++) {
if (!(x[i] in d)) {
d[x[i]] = 1;
} else {
return 0;
}
}
return 1;
}
function total(a) {
var i = 1;
while (i < a.length) {
var x = a[i];
i += 1;
if (x.length == 6) {
continue ;
}
for ( var j = 0; j < 6; j++) {
var z = j.toString();
if (possible(x + z)) {
a.push(x + z);
}
}
}
}
function PrintSolution(a, l, r) {
var ans1 = 0;
var ans2 = 0;
var low = 0;
var high = a.length - 1;
while (low <= high) {
var mid = Math.floor((low + high) / 2);
if (parseInt(a[mid]) === l) {
ans1 = mid;
break ;
}
if (parseInt(a[mid]) > l) {
ans1 = mid;
high = mid - 1;
} else {
low = mid + 1;
}
}
low = 0;
high = a.length - 1;
while (low <= high) {
var mid = Math.floor((low + high) / 2);
if (parseInt(a[mid]) === r) {
ans2 = mid;
break ;
}
if (parseInt(a[mid]) < r) {
ans2 = mid;
low = mid + 1;
} else {
high = mid - 1;
}
}
console.log(ans2 - ans1 + 1);
}
var a = [ '0' , '1' , '2' , '3' , '4' , '5' ];
total(a);
var l = 1;
var r = 1000;
PrintSolution(a, l, r);
|
Approach: Recursive Backtracking with Set-based Pruning
The steps of the “Recursive Backtracking with Set-based Pruning” approach are:
- Define a helper function count_numbers that takes a length n, a lower bound L, an upper bound R, and a set used that stores the digits already used in the current number.
- If n is zero, convert the current number stored in the list curr to an integer, and check if it satisfies the conditions: (a) the number is within the range [L, R], and (b) all its digits are distinct.
- If the conditions are satisfied, return 1 to indicate that a valid number is found. Otherwise, return 0.
- Initialize a counter count to zero, and loop over all possible digits d from 0 to 5.
- If d is zero and the length of curr is zero, skip this digit (because it cannot be the leading digit).
- If d is greater than 5, break the loop (because we have already checked all possible digits).
- If d is not in the set used, add it to used, append it to curr, and recursively call count_numbers with n-1, L, R, and used.
- After the recursive call, pop d from curr and remove it from used.
- Add the return value from the recursive call to the counter count.
- Return the final value of count after all recursive calls.
- In the main function count_distinct_numbers, loop over all possible lengths n from 1 to the number of digits in the upper bound R.
- For each length n, initialize an empty set used and an empty list curr, and call the helper function count_numbers with n, L, R, and used.
- Add the return value from count_numbers to a running total count.
- Return the final value of count after all iterations.
C++
#include <iostream>
#include <set>
#include <string>
#include <vector>
using namespace std;
int count_numbers( int n, int L, int R, set< int >& used,
vector< int >& curr)
{
if (n == 0) {
int num = stoi(to_string(curr[0]));
for ( int i = 1; i < curr.size(); i++) {
num = num * 10 + curr[i];
}
if (num >= L && num <= R
&& set< int >(curr.begin(), curr.end()).size()
== curr.size()) {
return 1;
}
else {
return 0;
}
}
int count = 0;
for ( int d = 0; d <= 5; d++) {
if (d == 0 && curr.empty()) {
continue ;
}
if (d > 5) {
break ;
}
if (!used.count(d)) {
used.insert(d);
curr.push_back(d);
count += count_numbers(n - 1, L, R, used, curr);
curr.pop_back();
used.erase(d);
}
}
return count;
}
int count_distinct_numbers( int L, int R)
{
int count = 0;
for ( int n = 1; n <= to_string(R).size(); n++) {
set< int > used;
vector< int > curr;
count += count_numbers(n, L, R, used, curr);
}
return count;
}
int main()
{
int L = 100;
int R = 1000;
cout << count_distinct_numbers(L, R)
<< endl;
return 0;
}
|
Java
import java.util.*;
public class Solution {
public static int countDistinctNumbers( int L, int R) {
int count = 0 ;
for ( int n = 1 ; n <= Integer.toString(R).length(); n++) {
Set<Integer> used = new HashSet<>();
List<Integer> curr = new ArrayList<>();
count += countNumbers(n, L, R, used, curr);
}
return count;
}
private static int countNumbers( int n, int L, int R, Set<Integer> used, List<Integer> curr) {
if (n == 0 ) {
int num = Integer.parseInt(curr.stream().map(String::valueOf).reduce( "" , String::concat));
if (L <= num && num <= R && new HashSet<>(curr).size() == curr.size()) {
return 1 ;
} else {
return 0 ;
}
}
int count = 0 ;
for ( int d = 0 ; d <= 5 ; d++) {
if (d == 0 && curr.isEmpty()) {
continue ;
}
if (used.contains(d)) {
continue ;
}
used.add(d);
curr.add(d);
count += countNumbers(n- 1 , L, R, used, curr);
curr.remove(curr.size()- 1 );
used.remove(d);
}
return count;
}
public static void main(String[] args) {
int L = 100 ;
int R = 1000 ;
System.out.println(countDistinctNumbers(L, R));
}
}
|
Python3
def count_distinct_numbers(L, R):
def count_numbers(n, L, R, used):
if n = = 0 :
num = int ("".join( map ( str , curr)))
if L < = num < = R and len ( set (curr)) = = len (curr):
return 1
else :
return 0
count = 0
for d in range ( 6 ):
if d = = 0 and len (curr) = = 0 :
continue
if d > 5 :
break
if d not in used:
used.add(d)
curr.append(d)
count + = count_numbers(n - 1 , L, R, used)
curr.pop()
used.remove(d)
return count
count = 0
for n in range ( 1 , len ( str (R)) + 1 ):
used = set ()
curr = []
count + = count_numbers(n, L, R, used)
return count
L = 100
R = 1000
print (count_distinct_numbers(L, R))
|
C#
using System;
using System.Collections.Generic;
namespace CountDistinctNumbers
{
class Program
{
static int CountNumbers( int n, int L, int R, HashSet< int > used, List< int > curr)
{
if (n == 0)
{
int num = int .Parse(curr[0].ToString());
for ( int i = 1; i < curr.Count; i++)
{
num = num * 10 + curr[i];
}
if (num >= L && num <= R && new HashSet< int >(curr).Count == curr.Count)
{
return 1;
}
else
{
return 0;
}
}
int count = 0;
for ( int d = 0; d <= 5; d++)
{
if (d == 0 && curr.Count == 0)
{
continue ;
}
if (d > 5)
{
break ;
}
if (!used.Contains(d))
{
used.Add(d);
curr.Add(d);
count += CountNumbers(n - 1, L, R, used, curr);
curr.RemoveAt(curr.Count - 1);
used.Remove(d);
}
}
return count;
}
static int CountDistinctNumbers( int L, int R)
{
int count = 0;
for ( int n = 1; n <= R.ToString().Length; n++)
{
HashSet< int > used = new HashSet< int >();
List< int > curr = new List< int >();
count += CountNumbers(n, L, R, used, curr);
}
return count;
}
static void Main( string [] args)
{
int L = 100;
int R = 1000;
Console.WriteLine(CountDistinctNumbers(L, R));
}
}
}
|
Javascript
function count_distinct_numbers(L, R) {
let curr = [];
function count_numbers(n, L, R, used) {
if (n === 0) {
let num = parseInt(curr.join( '' ));
if (L <= num && num <= R && new Set(curr).size === curr.length) {
return 1;
} else {
return 0;
}
}
let count = 0;
for (let d = 0; d < 6; d++) {
if (d === 0 && curr.length === 0) {
continue ;
}
if (d > 5) {
break ;
}
if (!used.has(d)) {
used.add(d);
curr.push(d);
count += count_numbers(n - 1, L, R, used);
curr.pop();
used. delete (d);
}
}
return count;
}
let count = 0;
for (let n = 1; n <= String(R).length; n++) {
let used = new Set();
count += count_numbers(n, L, R, used);
}
return count;
}
let L = 100;
let R = 1000;
console.log(count_distinct_numbers(L, R));
|
The time complexity of this approach is O(N^2), where N is the number of digits in the upper bound R.
The Auxiliary space is also O(N^2),
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...