Open In App

Count of integers of length N and value less than K such that they contain digits only from the given set

Last Updated : 31 May, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Given a set of digits A[] in sorted order and two integers N and K, the task is to find how many numbers of length N are possible whose value is less than K and the digits are from the given set only. Note that you can use the same digit multiple times.

Examples: 

Input: A[] = {0, 1, 5}, N = 1, K = 2 
Output:
Only valid numbers are 0 and 1.

Input: A[] = {0, 1, 2, 5}, N = 2, K = 21 
Output:
10, 11, 12, 15 and 20 are the valid numbers. 
 

Approach: Let d be the size of A[]. We can break this problem into three simpler cases.  

  1. When N is greater than the length of K, It is obvious that if the length of N is greater than the length of k or if d is equal to 0, no such number is possible.
  2. When N is smaller than the length of K, then all possible combinations of digit of length N are valid. Also, we have to keep in mind that 0 can’t be in the first place. So, if A[] contains 0, the first place can be filled in (d – 1) ways. Since repetition is allowed and 0 can occupy the other places, rest N – 1 places can be filled in d * d * … * d(N – 1) times i.e. in dN – 1 ways. Therefore the answer is (d – 1) * (dN – 1) if A[] contains 0 else dN.
  3. When N is equal to the length of K, this is the trickiest part. We need to use Dynamic Programming for this part. Construct a digit array of K. Let’s call it digit[]. Let First(i) be the number formed by taking the first i digits of it. Let lower[i] denote the number of elements in A[] which are smaller than i
    For example, First(2) of 423 is 42. If A[] = {0, 2} then lower[0] = 0, lower[1] = 1, lower[2] = 1, lower[3] = 2. 
    Generate N digit numbers by dynamic programming. Let dp[i] denote total numbers of length i which are less than first i digits of K
    Elements in dp[i] can be generated by two cases: 
    • For all the numbers whose First(i – 1) is less than First(i – 1) of K, we can put any digit at ith index. Hence, dp[i] = dp[i] + (dp[i – 1] * d)
    • For all the numbers whose First(i – 1) is the same as First(i – 1) of K, we can only put those digits which are smaller than digit[i]. Hence, dp[i] = dp[i] + lower[digit[i]].

Below is the implementation of the above approach:  

C++14




// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
 
#define MAX 10
 
// Function to convert a number into vector
vector<int> numToVec(int N)
{
    vector<int> digit;
 
    // Push all the digits of N from the end
    // one by one to the vector
    while (N != 0) {
        digit.push_back(N % 10);
        N = N / 10;
    }
 
    // If the original number was 0
    if (digit.size() == 0)
        digit.push_back(0);
 
    // Reverse the vector elements
    reverse(digit.begin(), digit.end());
 
    // Return the required vector
    return digit;
}
 
// Function to return the count of B length integers
// which are less than C and they
// contain digits from set A[] only
int solve(vector<int>& A, int B, int C)
{
    vector<int> digit;
    int d, d2;
 
    // Convert number to digit array
    digit = numToVec(C);
    d = A.size();
 
    // Case 1: No such number possible as the
    // generated numbers will always
    // be greater than C
    if (B > digit.size() || d == 0)
        return 0;
 
    // Case 2: All integers of length B are valid
    // as they all are less than C
    else if (B < digit.size()) {
        // contain 0
        if (A[0] == 0 && B != 1)
            return (d - 1) * pow(d, B - 1);
        else
            return pow(d, B);
    }
 
    // Case 3
    else {
        int dp[B + 1] = { 0 };
        int lower[MAX + 1] = { 0 };
 
        // Update the lower[] array such that
        // lower[i] stores the count of elements
        // in A[] which are less than i
        for (int i = 0; i < d; i++)
            lower[A[i] + 1] = 1;
        for (int i = 1; i <= MAX; i++)
            lower[i] = lower[i - 1] + lower[i];
 
        bool flag = true;
        dp[0] = 0;
        for (int i = 1; i <= B; i++) {
            d2 = lower[digit[i - 1]];
            dp[i] = dp[i - 1] * d;
 
            // For first index we can't use 0
            if (i == 1 && A[0] == 0 && B != 1)
                d2 = d2 - 1;
 
            // Whether (i-1) digit of generated number
            // can be equal to (i - 1) digit of C
            if (flag)
                dp[i] += d2;
 
            // Is digit[i - 1] present in A ?
            flag = (flag & (lower[digit[i - 1] + 1]
                            == lower[digit[i - 1]] + 1));
        }
        return dp[B];
    }
}
 
// Driver code
int main()
{
 
    // Digits array
    vector<int> A = { 0, 1, 2, 5 };
    int N = 2;
    int k = 21;
 
    cout << solve(A, N, k);
 
    return 0;
}


Java




// Java implementation of the approach
import java.util.*;
 
class GFG
{
static int MAX = 10;
 
// Function to convert a number into vector
static Vector<Integer> numToVec(int N)
{
    Vector<Integer> digit = new Vector<Integer>();
 
    // Push all the digits of N from the end
    // one by one to the vector
    while (N != 0)
    {
        digit.add(N % 10);
        N = N / 10;
    }
 
    // If the original number was 0
    if (digit.size() == 0)
        digit.add(0);
 
    // Reverse the vector elements
    Collections.reverse(digit);
 
    // Return the required vector
    return digit;
}
 
// Function to return the count
// of B length integers which are
// less than C and they contain
// digits from set A[] only
static int solve(Vector<Integer> A, int B, int C)
{
    Vector<Integer> digit = new Vector<Integer>();
    int d, d2;
 
    // Convert number to digit array
    digit = numToVec(C);
    d = A.size();
 
    // Case 1: No such number possible as the
    // generated numbers will always
    // be greater than C
    if (B > digit.size() || d == 0)
        return 0;
 
    // Case 2: All integers of length B are valid
    // as they all are less than C
    else if (B < digit.size())
    {
        // contain 0
        if (A.get(0) == 0 && B != 1)
            return (int) ((d - 1) * Math.pow(d, B - 1));
        else
            return (int) Math.pow(d, B);
    }
 
    // Case 3
    else
    {
        int []dp = new int[B + 1];
        int []lower = new int[MAX + 1];
 
        // Update the lower[] array such that
        // lower[i] stores the count of elements
        // in A[] which are less than i
        for (int i = 0; i < d; i++)
            lower[A.get(i) + 1] = 1;
        for (int i = 1; i <= MAX; i++)
            lower[i] = lower[i - 1] + lower[i];
 
        boolean flag = true;
        dp[0] = 0;
        for (int i = 1; i <= B; i++)
        {
            d2 = lower[digit.get(i - 1)];
            dp[i] = dp[i - 1] * d;
 
            // For first index we can't use 0
            if (i == 1 && A.get(0) == 0 && B != 1)
                d2 = d2 - 1;
 
            // Whether (i-1) digit of generated number
            // can be equal to (i - 1) digit of C
            if (flag)
                dp[i] += d2;
 
            // Is digit[i - 1] present in A ?
            flag = (flag & (lower[digit.get(i - 1) + 1] ==
                            lower[digit.get(i - 1)] + 1));
        }
        return dp[B];
    }
}
 
// Driver code
public static void main(String[] args)
{
    Integer arr[] = { 0, 1, 2, 5 };
    // Digits array
    Vector<Integer> A = new Vector<>(Arrays.asList(arr));
    int N = 2;
    int k = 21;
 
    System.out.println(solve(A, N, k));
}
}
 
// This code is contributed
// by PrinciRaj1992


Python3




# Python3 implementation of the approach
MAX=10
 
# Function to convert a number into vector
def numToVec(N):
     
    digit = []
 
    # Push all the digits of N from the end
    # one by one to the vector
    while (N != 0):
        digit.append(N % 10)
        N = N // 10
 
    # If the original number was 0
    if (len(digit) == 0):
        digit.append(0)
 
    # Reverse the vector elements
    digit = digit[::-1]
 
    # Return the required vector
    return digit
 
 
# Function to return the count of B length integers
# which are less than C and they
# contain digits from set A[] only
def solve(A, B, C):
    d, d2 = 0,0
 
    # Convert number to digit array
    digit = numToVec(C)
    d = len(A)
 
    # Case 1: No such number possible as the
    # generated numbers will always
    # be greater than C
    if (B > len(digit) or d == 0):
        return 0
 
    # Case 2: All integers of length B are valid
    # as they all are less than C
    elif (B < len(digit)):
        # contain 0
        if (A[0] == 0 and B != 1):
            return (d - 1) * pow(d, B - 1)
        else:
            return pow(d, B)
 
    # Case 3
    else :
        dp=[0 for i in range(B + 1)]
        lower=[0 for i in range(MAX + 1)]
 
        # Update the lower[] array such that
        # lower[i] stores the count of elements
        # in A[] which are less than i
        for i in range(d):
            lower[A[i] + 1] = 1
        for i in range(1, MAX+1):
            lower[i] = lower[i - 1] + lower[i]
 
        flag = True
        dp[0] = 0
        for i in range(1, B+1):
            d2 = lower[digit[i - 1]]
            dp[i] = dp[i - 1] * d
 
            # For first index we can't use 0
            if (i == 1 and A[0] == 0 and B != 1):
                d2 = d2 - 1
 
            # Whether (i-1) digit of generated number
            # can be equal to (i - 1) digit of C
            if (flag):
                dp[i] += d2
 
            # Is digit[i - 1] present in A ?
            flag = (flag & (lower[digit[i - 1] + 1] == lower[digit[i - 1]] + 1))
         
        return dp[B]
 
# Driver code
 
# Digits array
A =[0, 1, 2, 5]
N = 2
k = 21
 
print(solve(A, N, k))
 
# This code is contributed by mohit kumar 29


C#




// C# implementation of the approach
using System;
using System.Collections.Generic;
 
class GFG
{
static int MAX = 10;
 
// Function to convert a number into vector
static List<int> numToVec(int N)
{
    List<int> digit = new List<int>();
 
    // Push all the digits of N from the end
    // one by one to the vector
    while (N != 0)
    {
        digit.Add(N % 10);
        N = N / 10;
    }
 
    // If the original number was 0
    if (digit.Count == 0)
        digit.Add(0);
 
    // Reverse the vector elements
    digit.Reverse();
 
    // Return the required vector
    return digit;
}
 
// Function to return the count
// of B length integers which are
// less than C and they contain
// digits from set A[] only
static int solve(List<int> A, int B, int C)
{
    List<int> digit = new List<int>();
    int d, d2;
 
    // Convert number to digit array
    digit = numToVec(C);
    d = A.Count;
 
    // Case 1: No such number possible as the
    // generated numbers will always
    // be greater than C
    if (B > digit.Count || d == 0)
        return 0;
 
    // Case 2: All integers of length B are valid
    // as they all are less than C
    else if (B < digit.Count)
    {
        // contain 0
        if (A[0] == 0 && B != 1)
            return (int) ((d - 1) * Math.Pow(d, B - 1));
        else
            return (int) Math.Pow(d, B);
    }
 
    // Case 3
    else
    {
        int []dp = new int[B + 1];
        int []lower = new int[MAX + 1];
 
        // Update the lower[] array such that
        // lower[i] stores the count of elements
        // in A[] which are less than i
        for (int i = 0; i < d; i++)
            lower[A[i] + 1] = 1;
        for (int i = 1; i <= MAX; i++)
            lower[i] = lower[i - 1] + lower[i];
 
        Boolean flag = true;
        dp[0] = 0;
        for (int i = 1; i <= B; i++)
        {
            d2 = lower[digit[i-1]];
            dp[i] = dp[i - 1] * d;
 
            // For first index we can't use 0
            if (i == 1 && A[0] == 0 && B != 1)
                d2 = d2 - 1;
 
            // Whether (i-1) digit of generated number
            // can be equal to (i - 1) digit of C
            if (flag)
                dp[i] += d2;
 
            // Is digit[i - 1] present in A ?
            flag = (flag & (lower[digit[i-1] + 1] ==
                            lower[digit[i-1]] + 1));
        }
        return dp[B];
    }
}
 
// Driver code
public static void Main(String[] args)
{
    int []arr = { 0, 1, 2, 5 };
     
    // Digits array
    List<int> A = new List<int>(arr);
    int N = 2;
    int k = 21;
 
    Console.WriteLine(solve(A, N, k));
}
}
 
// This code is contributed by Rajput-Ji


Javascript




<script>
 
// Javascript implementation of the approach
let MAX = 10;
 
// Function to convert a number into vector
function numToVec(N)
{
    let digit = [];
         
    // Push all the digits of N from the end
    // one by one to the vector
    while (N != 0)
    {
        digit.push(N % 10);
        N = Math.floor(N / 10);
    }
   
    // If the original number was 0
    if (digit.length == 0)
        digit.push(0);
   
    // Reverse the vector elements
    digit.reverse();
   
    // Return the required vector
    return digit;
}
 
// Function to return the count
// of B length integers which are
// less than C and they contain
// digits from set A[] only
function solve(A, B, C)
{
    let digit = [];
    let d, d2;
   
    // Convert number to digit array
    digit = numToVec(C);
    d = A.length;
   
    // Case 1: No such number possible as the
    // generated numbers will always
    // be greater than C
    if (B > digit.length || d == 0)
        return 0;
   
    // Case 2: All integers of length B are valid
    // as they all are less than C
    else if (B < digit.length)
    {
         
        // contain 0
        if (A[0] == 0 && B != 1)
            return  Math.floor((d - 1) *
                    Math.pow(d, B - 1));
        else
            return Math.floor(Math.pow(d, B));
    }
   
    // Case 3
    else
    {
        let dp = new Array(B + 1);
        let lower = new Array(MAX + 1);
         
          for(let i = 0; i < dp.length; i++)
        {
            dp[i] = 0;
        }
        for(let i = 0; i < lower.length; i++)
        {
            lower[i] = 0;
        }
         
        // Update the lower[] array such that
        // lower[i] stores the count of elements
        // in A[] which are less than i
        for(let i = 0; i < d; i++)
            lower[A[i] + 1] = 1;
        for(let i = 1; i <= MAX; i++)
            lower[i] = lower[i - 1] + lower[i];
   
        let flag = true;
        dp[0] = 0;
        for(let i = 1; i <= B; i++)
        {
            d2 = lower[digit[i - 1]];
            dp[i] = dp[i - 1] * d;
   
            // For first index we can't use 0
            if (i == 1 && A[0] == 0 && B != 1)
                d2 = d2 - 1;
   
            // Whether (i-1) digit of generated number
            // can be equal to (i - 1) digit of C
            if (flag)
                dp[i] += d2;
   
            // Is digit[i - 1] present in A ?
            flag = (flag & (lower[digit[i - 1] + 1] ==
                            lower[digit[i - 1]] + 1));
        }
        return dp[B];
    }
}
 
// Driver code
let arr = [ 0, 1, 2, 5 ];
let N = 2;
let k = 21;
 
document.write(solve(arr, N, k));
     
// This code is contributed by patel2127
 
</script>


Output: 

5

 

Time complexity: O(N)
Auxiliary Space: O(N), since N extra space has been taken.



Similar Reads

Numbers of Length N having digits A and B and whose sum of digits contain only digits A and B
Given three positive integers N, A, and B. The task is to count the numbers of length N containing only digits A and B and whose sum of digits also contains the digits A and B only. Print the answer modulo 109 + 7.Examples: Input: N = 3, A = 1, B = 3 Output: 1 Possible numbers of length 3 are 113, 131, 111, 333, 311, 331 and so on... But only 111 i
15 min read
Find a Symmetric matrix of order N that contain integers from 0 to N-1 and main diagonal should contain only 0's
Given an integer N. The task is to generate a symmetric matrix of order N*N having the following properties. Main diagonal should contain only 0'sThe matrix should contain elements from 0 to N-1 only. Examples: Input: N = 4 Output: 0 2 3 1 2 0 1 3 3 1 0 2 1 3 2 0Input: N = 5 Output: 0 2 3 4 1 2 0 4 1 3 3 4 0 2 1 4 1 2 0 3 1 3 1 3 0 Approach: Since
10 min read
Count of Integers in given range consisting only given set of Digits
Given two integers L and R, and an array arr[] containing single digit integers, the task is to find all the integers in the range [L, R) consisting of digits from given array of digits. Examples: Input: L = 1, R = 100, arr[] = {2, 3, 5, 7}Output: 20Explanation: The number between 1 and 100 total integers which are made up with 2, 3, 5, 7 are:2, 3,
5 min read
Find an integer such that if it is multiplied by any of the given integers they form G.P.
Given three integers A, B, and C, the task is to find out a positive integer K (if exists) such that if k is multiplied by any of the given integers A, B, or C they form G.P.(Geometric Progression) in the given order. If there exists no K print -1. Examples: Input: A = 1, B = 9, C = 27Output: 3Explanation: If A is multiplied by 3 then the integers
6 min read
Maximum length L such that the sum of all subarrays of length L is less than K
Given an array of length N and an integer K. The task is to find the maximum length L such that all the subarrays of length L have sum of its elements less than K.Examples: Input: arr[] = {1, 2, 3, 4, 5}, K = 20 Output: 5 The only subarray of length 5 is the complete array and (1 + 2 + 3 + 4 + 5) = 15 &lt; 20. Input: arr[] = {1, 2, 3, 4, 5}, K = 10
8 min read
Count of Numbers such that difference between the number and sum of its digits not less than L
Given a Natural number N and a whole number L, the task is to find the count of numbers, smaller than or equal to N, such that the difference between the number and sum of its digits is not less than L.Examples: Input: N = 1500, L = 30 Output: 1461 Input: N = 1546300, L = 30651 Output: 1515631 Approach: Our solution depends on a simple observation
6 min read
Count numbers in given range such that sum of even digits is greater than sum of odd digits
Given two integers L and R denoting a range [L, R]. The task is to find the total count of numbers in the given range [L,R] whose sum of even digits is greater than the sum of odd digits. Examples: Input : L=2 R=10 Output : 4 Numbers having the property that sum of even digits is greater than sum of odd digits are: 2, 4, 6, 8 Input : L=2 R=17 Outpu
14 min read
Count of alphabets having ASCII value less than and greater than k
Given a string, the task is to count the number of alphabets having ASCII values less than and greater than or equal to a given integer k. Examples: Input: str = "GeeksForGeeks", k = 90Output:3, 10G, F, G have ascii values less than 90.e, e, k, s, o, r, e, e, k, s have ASCII values greater than or equal to 90 Input: str = "geeksforgeeks", k = 90Out
11 min read
Recursive program to print all numbers less than N which consist of digits 1 or 3 only
Given an integer N, the task is to print all the numbers ? N which have their digits as only 1 or 3.Examples: Input: N = 10 Output: 3 1 Input: N = 20 Output: 13 11 3 1 Approach: First, check if the number is greater than 0. If yes then proceed further, else program is terminated.Check for the presence of digits 1 or 3 at each place of the number.If
7 min read
Count numbers less than N containing digits from the given set : Digit DP
Given an integer N and set of digits D[], which consists of digits from [1, 9]. The task is to count the numbers possible less than N, whose digits are from the given set of digits. Examples: Input: D = ["1", "4", "9"], N = 10 Output: 3 Explanation: There are only 3 numbers possible less than 3 with given set of digits - 1, 4, 9 Input: D[] = {"1",
13 min read