Counting numbers of n digits that are monotone
Call decimal number a monotone if: . Write a program that takes the positive number n on input and returns a number of decimal numbers of length n that are monotone. Numbers can’t start with 0.
Examples :
Input : 1
Output : 9
Numbers are 1, 2, 3, ... 9
Input : 2
Output : 45
Numbers are 11, 12, 13, .... 22, 23
...29, 33, 34, ... 39.
Count is 9 + 8 + 7 ... + 1 = 45
Explanation: Let’s start by example of monotone numbers:All those numbers are monotone as each digit on higher place is than the one before it. What are the monotone numbers are of length 1 and digits 1 or 2? It is question to ask yourself at the very beginning. We can see that possible numbers are: That was easy, now lets expand the question to digits 1, 2 and 3: Now different question, what are the different monotone numbers consisting of only 1 and length 3 are there? Lets try now draw this very simple observation in 2 dimensional array for number of length 3, where first column is the length of string and first row is possible digits: Let’s try to fill 3rd row 3rd column(number of monotone numbers consisting from numbers 1 or 2 with length 2). This should be: If we will look closer we already have subsets of this set i.e: – Monotone numbers that has length 2 and consist of 1 or 2 – Monotone numbers of length 2 and consisting of number 2 We just need to add previous values to get the longer one. Final matrix should look like this:
C++
#include <cstring>
#include <iostream>
int static const DP_s = 9;
int getNumMonotone( int len)
{
int DP[len][DP_s];
memset (DP, 0, sizeof (DP));
for ( int i = 0; i < DP_s; ++i)
DP[0][i] = i + 1;
for ( int i = 0; i < len; ++i)
DP[i][0] = 1;
for ( int i = 1; i < len; ++i)
for ( int j = 1; j < DP_s; ++j)
DP[i][j] = DP[i - 1][j] + DP[i][j - 1];
return DP[len - 1][DP_s - 1];
}
int main()
{
std::cout << getNumMonotone(10);
return 0;
}
|
C
#include <stdio.h>
#include <string.h>
int static const DP_s = 9;
int getNumMonotone( int len)
{
int DP[len][DP_s];
memset (DP, 0, sizeof (DP));
for ( int i = 0; i < DP_s; ++i)
DP[0][i] = i + 1;
for ( int i = 0; i < len; ++i)
DP[i][0] = 1;
for ( int i = 1; i < len; ++i)
for ( int j = 1; j < DP_s; ++j)
DP[i][j] = DP[i - 1][j] + DP[i][j - 1];
return DP[len - 1][DP_s - 1];
}
int main()
{
printf ( "%d" , getNumMonotone(10));
return 0;
}
|
Java
class GFG
{
static final int DP_s = 9 ;
static int getNumMonotone( int len)
{
int [][] DP = new int [len][DP_s];
for ( int i = 0 ; i < DP_s; ++i)
DP[ 0 ][i] = i + 1 ;
for ( int i = 0 ; i < len; ++i)
DP[i][ 0 ] = 1 ;
for ( int i = 1 ; i < len; ++i)
for ( int j = 1 ; j < DP_s; ++j)
DP[i][j] = DP[i - 1 ][j]
+ DP[i][j - 1 ];
return DP[len - 1 ][DP_s - 1 ];
}
public static void main (String[] args)
{
System.out.println(getNumMonotone( 10 ));
}
}
|
Python3
DP_s = 9
def getNumMonotone(ln):
DP = [[ 0 ] * DP_s for i in range (ln)]
for i in range (DP_s):
DP[ 0 ][i] = i + 1
for i in range (ln):
DP[i][ 0 ] = 1
for i in range ( 1 , ln):
for j in range ( 1 , DP_s):
DP[i][j] = DP[i - 1 ][j] + DP[i][j - 1 ]
return DP[ln - 1 ][DP_s - 1 ]
print (getNumMonotone( 10 ))
|
C#
using System;
class GFG
{
static int DP_s = 9;
static int getNumMonotone( int len)
{
int [,] DP = new int [len,DP_s];
for ( int i = 0; i < DP_s; ++i)
DP[0,i] = i + 1;
for ( int i = 0; i < len; ++i)
DP[i,0] = 1;
for ( int i = 1; i < len; ++i)
for ( int j = 1; j < DP_s; ++j)
DP[i,j] = DP[i - 1,j]
+ DP[i,j - 1];
return DP[len - 1,DP_s - 1];
}
public static void Main ()
{
Console.WriteLine(getNumMonotone(10));
}
}
|
Javascript
<script>
let DP_s = 9
function getNumMonotone(ln){
let DP = new Array(ln).fill(0).map(()=> new Array(DP_s).fill(0))
for (let i=0;i<DP_s;i++){
DP[0][i] = i + 1
}
for (let i=0;i<ln;i++)
DP[i][0] = 1
for (let i=1;i<ln;i++){
for (let j=1;j<DP_s;j++){
DP[i][j] = DP[i - 1][j] + DP[i][j - 1]
}
}
return DP[ln - 1][DP_s - 1]
}
document.write(getNumMonotone(10), "</br>" )
</script>
|
PHP
<?php
function getNumMonotone( $len )
{
$DP_s = 9;
$DP = array ( array_fill (0, $len , 0),
array_fill (0, $len , 0));
for ( $i = 0; $i < $DP_s ; ++ $i )
$DP [0][ $i ] = $i + 1;
for ( $i = 0; $i < $len ; ++ $i )
$DP [ $i ][0] = 1;
for ( $i = 1; $i < $len ; ++ $i )
for ( $j = 1; $j < $DP_s ; ++ $j )
$DP [ $i ][ $j ] = $DP [ $i - 1][ $j ] +
$DP [ $i ][ $j - 1];
return $DP [ $len - 1][ $DP_s - 1];
}
echo getNumMonotone(10);
?>
|
Time complexity: O(n*DP_s)
Auxiliary space: O(n*DP_s)
Efficient approach : Space optimization
In previous approach the current value dp[i][j] is only depend upon the current and previous row values of DP. So to optimize the space complexity we use a single 1D array to store the computations.
Implementation steps:
- Create a 1D vector dp of size DP_s.
- Set a base case by initializing the values of DP .
- Now iterate over subproblems by the help of nested loop and get the current value from previous computations.
- At last return and print the final answer stored dp[Dp_s-1] .
Implementation:
C++
#include <cstring>
#include <iostream>
int static const DP_s = 9;
int getNumMonotone( int len)
{
int DP[DP_s];
memset (DP, 0, sizeof (DP));
for ( int i = 0; i < DP_s; ++i)
DP[i] = i + 1;
for ( int i = 1; i < len; ++i)
for ( int j = 1; j < DP_s; ++j)
DP[j] += DP[j - 1];
return DP[DP_s - 1];
}
int main()
{
std::cout << getNumMonotone(10);
return 0;
}
|
Java
public class MonotoneNumbers {
static final int DP_SIZE = 9 ;
public static int getNumMonotone( int len) {
int [] DP = new int [DP_SIZE];
for ( int i = 0 ; i < DP_SIZE; i++) {
DP[i] = i + 1 ;
}
for ( int i = 1 ; i < len; i++) {
for ( int j = 1 ; j < DP_SIZE; j++) {
DP[j] += DP[j - 1 ];
}
}
return DP[DP_SIZE - 1 ];
}
public static void main(String[] args) {
int n = 10 ;
int result = getNumMonotone(n);
System.out.println(result);
}
}
|
Python3
def get_num_monotone(length):
dp = [ 0 ] * 9
for i in range ( 9 ):
dp[i] = i + 1
for i in range ( 1 , length):
for j in range ( 1 , 9 ):
dp[j] + = dp[j - 1 ]
return dp[ 8 ]
if __name__ = = "__main__" :
result = get_num_monotone( 10 )
print (result)
|
C#
using System;
class GFG
{
const int DP_s = 9;
static int GetNumMonotone( int len)
{
int [] DP = new int [DP_s];
for ( int i = 0; i < DP_s; ++i)
DP[i] = i + 1;
for ( int i = 1; i < len; ++i)
for ( int j = 1; j < DP_s; ++j)
DP[j] += DP[j - 1];
return DP[DP_s - 1];
}
static void Main()
{
Console.WriteLine(GetNumMonotone(10));
}
}
|
Javascript
const DP_s = 9;
function getNumMonotone(len) {
let DP = new Array(DP_s).fill(0);
for (let i = 0; i < DP_s; ++i)
DP[i] = i + 1;
for (let i = 1; i < len; ++i)
for (let j = 1; j < DP_s; ++j)
DP[j] += DP[j - 1];
return DP[DP_s - 1];
}
console.log(getNumMonotone(10));
|
Output
43758
Time complexity: O(n*DP_s)
Auxiliary space: O(DP_s)
Last Updated :
02 Dec, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...