GeeksforGeeks App
Open App
Browser
Continue

Count of N-digit numbers in base K with no two consecutive zeroes

Given two integers N and K, the task is to find the count of all the integer in base K which satisfy the following conditions:

1. The integers must be of exactly N digits.
2. There should be no leading 0.
3. There must not be any consecutive digit pair such that both the digits are 0.

Examples:

```Input: N = 3, K = 10
Output: 891
All 3-digit numbers in base 10 are from the range [100, 999]
Out of these numbers only 100, 200, 300, 400, ..., 900 are invalid.
Hence valid integers are 900 - 9 = 891```
```Input: N = 2, K = 10
Output: 90  ```

Naive approach: Write a function count_numbers(int k, int n, bool flag) which will return the count of N digit numbers possible of base K and flag will tell whether the previously chosen digit was 0 or not. Call this function recursively for count_numbers(int k, int n-1, bool flag), and using the flag, the occurrence of two consecutive 0s can be avoided.

Below is the implementation of the above approach:

C++

 `// C++ implementation of the approach``#include ``using` `namespace` `std;` `// Function to return the count of``// n-digit numbers that satisfy``// the given conditions``int` `count_numbers(``int` `k, ``int` `n, ``bool` `flag)``{` `    ``// Base case``    ``if` `(n == 1) {` `        ``// If 0 wasn't chosen previously``        ``if` `(flag) {``            ``return` `(k - 1);``        ``}``        ``else` `{``            ``return` `1;``        ``}``    ``}` `    ``// If 0 wasn't chosen previously``    ``if` `(flag)``        ``return` `(k - 1) * (count_numbers(k, n - 1, 0)``                          ``+ count_numbers(k, n - 1, 1));``    ``else``        ``return` `count_numbers(k, n - 1, 1);``}` `// Driver code``int` `main()``{``    ``int` `n = 3;``    ``int` `k = 10;``    ``cout << count_numbers(k, n, ``true``);` `    ``return` `0;``}`

Java

 `// Java implementation of the approach``class` `GFG``{``    ` `// Function to return the count of``// n-digit numbers that satisfy``// the given conditions``static` `int` `count_numbers(``int` `k, ``int` `n,``                         ``boolean` `flag)``{` `    ``// Base case``    ``if` `(n == ``1``)``    ``{` `        ``// If 0 wasn't chosen previously``        ``if` `(flag)``        ``{``            ``return` `(k - ``1``);``        ``}``        ``else``        ``{``            ``return` `1``;``        ``}``    ``}` `    ``// If 0 wasn't chosen previously``    ``if` `(flag)``        ``return` `(k - ``1``) * (count_numbers(k, n - ``1``, ``false``) +``                          ``count_numbers(k, n - ``1``, ``true``));``    ``else``        ``return` `count_numbers(k, n - ``1``, ``true``);``}` `// Driver code``public` `static` `void` `main (String[] args)``{``    ``int` `n = ``3``;``    ``int` `k = ``10``;``    ``System.out.println(count_numbers(k, n, ``true``));``}``}` `// This code is contributed by AnkitRai01`

Python3

 `# Python3 implementation of the approach` `# Function to return the count of``# n-digit numbers that satisfy``# the given conditions``def` `count_numbers(k, n, flag) :` `    ``# Base case``    ``if` `(n ``=``=` `1``) :` `        ``# If 0 wasn't chosen previously``        ``if` `(flag) :``            ``return` `(k ``-` `1``)``        ``else` `:``            ``return` `1` `    ``# If 0 wasn't chosen previously``    ``if` `(flag) :``        ``return` `(k ``-` `1``) ``*` `(count_numbers(k, n ``-` `1``, ``0``) ``+``                          ``count_numbers(k, n ``-` `1``, ``1``))``    ``else` `:``        ``return` `count_numbers(k, n ``-` `1``, ``1``)` `# Driver code``n ``=` `3``k ``=` `10``print``(count_numbers(k, n, ``True``))` `# This code is contributed by``# divyamohan123`

C#

 `// C# implementation of the approach``using` `System;``                    ` `class` `GFG``{``    ` `// Function to return the count of``// n-digit numbers that satisfy``// the given conditions``static` `int` `count_numbers(``int` `k, ``int` `n,``                         ``bool` `flag)``{` `    ``// Base case``    ``if` `(n == 1)``    ``{` `        ``// If 0 wasn't chosen previously``        ``if` `(flag)``        ``{``            ``return` `(k - 1);``        ``}``        ``else``        ``{``            ``return` `1;``        ``}``    ``}` `    ``// If 0 wasn't chosen previously``    ``if` `(flag)``        ``return` `(k - 1) * (count_numbers(k, n - 1, ``false``) +``                          ``count_numbers(k, n - 1, ``true``));``    ``else``        ``return` `count_numbers(k, n - 1, ``true``);``}` `// Driver code``public` `static` `void` `Main (String[] args)``{``    ``int` `n = 3;``    ``int` `k = 10;``    ``Console.Write(count_numbers(k, n, ``true``));``}``}` `// This code is contributed by 29AjayKuma`

Javascript

 ``

Output:

`891`

Time Complexity: O(n2)
Auxiliary Space: O(n2)

Approach 2: Efficient

Now that the problem has been solved using recursion, a 2-D DP can be used to solve this problem dp[n + 1][2] where dp[i][0] will give the number of i digit numbers possible ending with 0 and dp[i][1] will give the number of i digit numbers possible ending with non-zero.

The recurrence relation will be:

```dp[i][0] = dp[i - 1][1];
dp[i][1] = (dp[i - 1][0] + dp[i - 1][1]) * (K - 1); ```

Below is the implementation of the above approach:

C++

 `// C++ implementation of the approach``#include ``using` `namespace` `std;` `// Function to return the count of``// n-digit numbers that satisfy``// the given conditions``int` `count_numbers(``int` `k, ``int` `n)``{` `    ``// DP array to store the``    ``// pre-calculated states``    ``int` `dp[n + 1][2];` `    ``// Base cases``    ``dp[1][0] = 0;``    ``dp[1][1] = k - 1;``    ``for` `(``int` `i = 2; i <= n; i++) {` `        ``// i-digit numbers ending with 0``        ``// can be formed by concatenating``        ``// 0 in the end of all the (i - 1)-digit``        ``// number ending at a non-zero digit``        ``dp[i][0] = dp[i - 1][1];` `        ``// i-digit numbers ending with non-zero``        ``// can be formed by concatenating any non-zero``        ``// digit in the end of all the (i - 1)-digit``        ``// number ending with any digit``        ``dp[i][1] = (dp[i - 1][0] + dp[i - 1][1]) * (k - 1);``    ``}` `    ``// n-digit number ending with``    ``// and ending with non-zero``    ``return` `dp[n][0] + dp[n][1];``}` `// Driver code``int` `main()``{``    ``int` `k = 10;``    ``int` `n = 3;``    ``cout << count_numbers(k, n);` `    ``return` `0;``}`

Java

 `// Java implementation of the approach``import` `java.util.*;` `class` `GFG {` `    ``// Function to return the count of``    ``// n-digit numbers that satisfy``    ``// the given conditions``    ``static` `int` `count_numbers(``int` `k, ``int` `n)``    ``{` `        ``// DP array to store the``        ``// pre-calculated states``        ``int``[][] dp = ``new` `int``[n + ``1``][``2``];` `        ``// Base cases``        ``dp[``1``][``0``] = ``0``;``        ``dp[``1``][``1``] = k - ``1``;``        ``for` `(``int` `i = ``2``; i <= n; i++) {` `            ``// i-digit numbers ending with 0``            ``// can be formed by concatenating``            ``// 0 in the end of all the (i - 1)-digit``            ``// number ending at a non-zero digit``            ``dp[i][``0``] = dp[i - ``1``][``1``];` `            ``// i-digit numbers ending with non-zero``            ``// can be formed by concatenating any non-zero``            ``// digit in the end of all the (i - 1)-digit``            ``// number ending with any digit``            ``dp[i][``1``]``                ``= (dp[i - ``1``][``0``] + dp[i - ``1``][``1``]) * (k - ``1``);``        ``}` `        ``// n-digit number ending with``        ``// and ending with non-zero``        ``return` `dp[n][``0``] + dp[n][``1``];``    ``}` `    ``// Driver code``    ``public` `static` `void` `main(String[] args)``    ``{``        ``int` `k = ``10``;``        ``int` `n = ``3``;``        ``System.out.println(count_numbers(k, n));``    ``}``}` `// This code is contributed by Rajput-Ji`

Python3

 `# Python3 implementation of the approach` `# Function to return the count of``# n-digit numbers that satisfy``# the given conditions`  `def` `count_numbers(k, n):` `    ``# DP array to store the``    ``# pre-calculated states``    ``dp ``=` `[[``0` `for` `i ``in` `range``(``2``)]``          ``for` `i ``in` `range``(n ``+` `1``)]` `    ``# Base cases``    ``dp[``1``][``0``] ``=` `0``    ``dp[``1``][``1``] ``=` `k ``-` `1``    ``for` `i ``in` `range``(``2``, n ``+` `1``):` `        ``# i-digit numbers ending with 0``        ``# can be formed by concatenating``        ``# 0 in the end of all the (i - 1)-digit``        ``# number ending at a non-zero digit``        ``dp[i][``0``] ``=` `dp[i ``-` `1``][``1``]` `        ``# i-digit numbers ending with non-zero``        ``# can be formed by concatenating any non-zero``        ``# digit in the end of all the (i - 1)-digit``        ``# number ending with any digit``        ``dp[i][``1``] ``=` `(dp[i ``-` `1``][``0``] ``+``                    ``dp[i ``-` `1``][``1``]) ``*` `(k ``-` `1``)` `    ``# n-digit number ending with``    ``# and ending with non-zero``    ``return` `dp[n][``0``] ``+` `dp[n][``1``]`  `# Driver code``k ``=` `10``n ``=` `3``print``(count_numbers(k, n))` `# This code is contributed by Mohit Kumar`

C#

 `// C# implementation of the approach``using` `System;` `class` `GFG {` `    ``// Function to return the count of``    ``// n-digit numbers that satisfy``    ``// the given conditions``    ``static` `int` `count_numbers(``int` `k, ``int` `n)``    ``{` `        ``// DP array to store the``        ``// pre-calculated states``        ``int``[, ] dp = ``new` `int``[n + 1, 2];` `        ``// Base cases``        ``dp[1, 0] = 0;``        ``dp[1, 1] = k - 1;``        ``for` `(``int` `i = 2; i <= n; i++) {` `            ``// i-digit numbers ending with 0``            ``// can be formed by concatenating``            ``// 0 in the end of all the (i - 1)-digit``            ``// number ending at a non-zero digit``            ``dp[i, 0] = dp[i - 1, 1];` `            ``// i-digit numbers ending with non-zero``            ``// can be formed by concatenating any non-zero``            ``// digit in the end of all the (i - 1)-digit``            ``// number ending with any digit``            ``dp[i, 1]``                ``= (dp[i - 1, 0] + dp[i - 1, 1]) * (k - 1);``        ``}` `        ``// n-digit number ending with``        ``// and ending with non-zero``        ``return` `dp[n, 0] + dp[n, 1];``    ``}` `    ``// Driver code``    ``public` `static` `void` `Main(String[] args)``    ``{``        ``int` `k = 10;``        ``int` `n = 3;``        ``Console.WriteLine(count_numbers(k, n));``    ``}``}` `// This code is contributed by 29AjayKumar`

Javascript

 ``

Output:

`891`

Time Complexity: O(n)
Auxiliary Space: O(n)

Approach 3: More Efficient

Space optimize O(1)

In the previous approach, the current value dp[i] is only depend upon the previous values dp[i-1] .So to optimize the space complexity we can use variables to store current and previous computations instead of dp array of size n.

Implementation Steps:

• Initialize prev_zero to 0 and prev_nonzero to k-1.
• Loop from i=2 to i=n:
• Calculate curr_zero as prev_nonzero.
• Calculate curr_nonzero as (prev_zero + prev_nonzero) * (k-1).
• Update prev_zero to curr_zero and prev_nonzero to curr_nonzero.
• Return prev_zero + prev_nonzero.

Implementation:

C++

 `// C++ program for above approach` `#include ``using` `namespace` `std;` `// Function to return the count of``// n-digit numbers that satisfy``// the given conditions``int` `count_numbers(``int` `k, ``int` `n)``{``    ``// to store previous and current computations``    ``int` `prev_zero = 0, prev_nonzero = k - 1, curr_zero,``        ``curr_nonzero;` `    ``// iterate over subproblems``    ``for` `(``int` `i = 2; i <= n; i++) {``        ``// i-digit numbers ending with 0``        ``// can be formed by concatenating``        ``// 0 in the end of all the (i - 1)-digit``        ``// number ending at a non-zero digit``        ``curr_zero = prev_nonzero;``        ``curr_nonzero = (prev_zero + prev_nonzero) * (k - 1);` `        ``// assigning values to compute further``        ``prev_zero = curr_zero;``        ``prev_nonzero = curr_nonzero;``    ``}` `    ``// n-digit number ending with``    ``// and ending with non-zero``    ``return` `prev_zero + prev_nonzero;``}` `// Driver Code``int` `main()``{``    ``int` `k = 10;``    ``int` `n = 3;` `    ``// function call``    ``cout << count_numbers(k, n) << endl;``    ``return` `0;``}`

Python3

 `def` `count_numbers(k: ``int``, n: ``int``) ``-``> ``int``:``    ``# to store previous and current computations``    ``prev_zero ``=` `0``    ``prev_nonzero ``=` `k ``-` `1``    ``curr_zero ``=` `0``    ``curr_nonzero ``=` `0` `    ``# iterate over subproblems``    ``for` `i ``in` `range``(``2``, n ``+` `1``):``        ``# i-digit numbers ending with 0``        ``# can be formed by concatenating``        ``# 0 in the end of all the (i - 1)-digit``        ``# number ending at a non-zero digit``        ``curr_zero ``=` `prev_nonzero``        ``curr_nonzero ``=` `(prev_zero ``+` `prev_nonzero) ``*` `(k ``-` `1``)` `        ``# assigning values to compute further``        ``prev_zero ``=` `curr_zero``        ``prev_nonzero ``=` `curr_nonzero` `    ``# n-digit number ending with``    ``# and ending with non-zero``    ``return` `prev_zero ``+` `prev_nonzero`  `# Driver Code``if` `__name__ ``=``=` `'__main__'``:``    ``k ``=` `10``    ``n ``=` `3` `    ``# function call``    ``print``(count_numbers(k, n))`

Java

 `public` `class` `Main {` `    ``// Function to return the count of``    ``// n-digit numbers that satisfy``    ``// the given conditions``    ``public` `static` `int` `countNumbers(``int` `k, ``int` `n)``    ``{``        ``// Stores the previous and current``        ``// computations``        ``int` `prevZero = ``0``, prevNonZero = k - ``1``;``        ``int` `currZero, currNonZero;` `        ``// iterate over subproblems``        ``for` `(``int` `i = ``2``; i <= n; i++) {` `            ``// i-digit numbers ending with 0``            ``// can be formed by concatenating``            ``// 0 in the end of all the (i - 1)-digit``            ``// number ending at a non-zero digit``            ``currZero = prevNonZero;``            ``currNonZero``                ``= (prevZero + prevNonZero) * (k - ``1``);` `            ``// assigning values to``            ``// compute further``            ``prevZero = currZero;``            ``prevNonZero = currNonZero;``        ``}` `        ``// n-digit number ending with``        ``// and ending with non-zero``        ``return` `prevZero + prevNonZero;``    ``}` `    ``// Driver Code``    ``public` `static` `void` `main(String[] args)``    ``{``        ``int` `k = ``10``;``        ``int` `n = ``3``;``        ``System.out.println(countNumbers(k, n));``    ``}``}`

C#

 `using` `System;` `class` `CountNumbers``{``    ``static` `int` `Count(``int` `k, ``int` `n)``    ``{``        ``int` `prevZero = 0, prevNonZero = k - 1, currZero, currNonZero;` `        ``for` `(``int` `i = 2; i <= n; i++)``        ``{``            ``currZero = prevNonZero;``            ``currNonZero = (prevZero + prevNonZero) * (k - 1);` `            ``prevZero = currZero;``            ``prevNonZero = currNonZero;``        ``}` `        ``return` `prevZero + prevNonZero;``    ``}` `    ``static` `void` `Main()``    ``{``        ``int` `k = 10, n = 3;``        ``Console.WriteLine(Count(k, n));``    ``}``}`

Javascript

 `// Define a function named countNumbers``// that takes two arguments, k and n``function` `countNumbers(k, n)``{` `  ``// Initialize variables to keep track of``  ``// the count of numbers with a zero and``  ``// non-zero starting digit``  ``let prevZero = 0, prevNonZero = k - 1;``  ` `  ``// Declare variables to store the current count``  ``// of numbers with a zero and non-zero starting digit``  ``let currZero, currNonZero;` `  ``// Loop through all possible lengths of numbers up to n``  ``for` `(let i = 2; i <= n; i++)``  ``{``  ` `    ``// The count of numbers of length i that``    ``// start with a zero is equal to the count``    ``// of numbers of length i-1 that start with a non-zero digit``    ``currZero = prevNonZero;``    ` `    ``// The count of numbers of length i that``    ``// start with a non-zero digit is equal to``    ``// the sum of counts of numbers of length i-1``    ``// that start with a zero or non-zero``    ``// digit multiplied by k-1 (since there are k-1 possible non-zero digits)``    ``currNonZero = (prevZero + prevNonZero) * (k - 1);` `    ``// Update the previous counts of numbers with``    ``// a zero and non-zero starting digit for the next iteration``    ``prevZero = currZero;``    ``prevNonZero = currNonZero;``  ``}` `  ``// Return the total count of numbers with``  ``/// a zero and non-zero starting digit``  ``return` `prevZero + prevNonZero;``}` `// Set the values of k and n``const k = 10;``const n = 3;` `// Call the countNumbers function with k and n``// as arguments and log the result to the console``console.log(countNumbers(k, n));`

Output:

`891`

Time complexity: O(N)
Auxiliary Space: O(1)

Approach:

1. The code defines a function `isValid` that checks if a digit is valid based on the condition of not having a consecutive pair of zeros.

2. The `backtrack` function generates all possible combinations of digits for valid integers by recursively exploring each digit at each index, excluding leading zeros.

3. The `countValidIntegers` function initializes a count variable and calls the `backtrack` function to count the valid integers.

4. The main function initializes the values of N and K, calls `countValidIntegers`, and outputs the result.

Below is the implementation of the above approach:

C++

 `#include ``#include ` `using` `namespace` `std;` `bool` `isValid(``const` `vector<``int``>& number, ``int` `index, ``int` `digit);` `void` `backtrack(vector<``int``>& number, ``int` `index, ``int` `N, ``int` `K, ``int``& count) {``    ``if` `(index == N) {``        ``count++;``        ``return``;``    ``}` `    ``// Skip generating numbers with leading zeros``    ``int` `start = (index == 0) ? 1 : 0;` `    ``for` `(``int` `digit = start; digit < K; digit++) {``        ``if` `(isValid(number, index, digit)) {``            ``number[index] = digit;``            ``backtrack(number, index + 1, N, K, count);``        ``}``    ``}``}` `bool` `isValid(``const` `vector<``int``>& number, ``int` `index, ``int` `digit) {``    ``if` `(index > 0 && number[index - 1] == 0 && digit == 0) {``        ``return` `false``;  ``// consecutive digit pair of zero``    ``}``    ``return` `true``;``}` `int` `countValidIntegers(``int` `N, ``int` `K) {``    ``vector<``int``> number(N);  ``// to store the digits of the number``    ``int` `count = 0;``    ``backtrack(number, 0, N, K, count);``    ``return` `count;``}` `int` `main() {``    ``int` `N = 3;``    ``int` `K = 10;` `    ``int` `result = countValidIntegers(N, K);``    ``cout << result << endl;` `    ``return` `0;``}`

Output

```891
```

Time Complexity: O(K^N)

The backtrack function is called recursively for each digit at each index, excluding leading zeros. The number of recursive calls depends on the value of N and K.
The number of possible digit choices at each index is K, so the total number of recursive calls is K^N.
As a result, the time complexity of the code is O(K^N), where K is the base and N is the number of digits.

Space Complexity:O(N)

The space complexity is determined by the space used by the number vector and the recursive calls.
The number vector stores the digits of the number and requires N units of space.
The recursive calls create a call stack, which can have a maximum depth of N.
Therefore, the space complexity of the code is O(N), where N is the number of digits

My Personal Notes arrow_drop_up