Given a number n, count the numbers from 1 to n that contain 4 as one of their digits.
Examples:Â
Input: n = 9
Output: 1
Explanation: 4 is the only number from 1 to 9 that contains the digit 4.Input: n = 50
Output: 14
Explanation: The numbers from 1 to 50 containing the digit 4 are: 4, 14, 24, 34, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49. Hence, the total count is 14.
Table of Content
[Naive Approach] Check Every Number From 1 to n - O(n log n) Time and O(1) Space
The idea is to check each number from 1 to n and determine whether it contains the digit 4.
Traverse all numbers from 1 to n. For each number, examine its digits one by one:
- Use n % 10 to get the last digit.
- If the digit is 4, the number contains 4.
- Otherwise, remove the last digit using integer division by 10 and continue.
- If the number contains 4, increment the count.
#include <bits/stdc++.h>
using namespace std;
// Function to check if a number contains digit 4
bool containsFour(int n) {
while (n > 0) {
// If digit is 4, return true
if (n % 10 == 4) {
return true;
}
// Move to next digit
n /= 10;
}
return false;
}
int countNumberswith4(int n) {
int count = 0;
for (int i = 1; i <= n; i++) {
// Increment count if i contains digit 4
if (containsFour(i)) {
count++;
}
}
return count;
}
int main() {
int n = 50;
cout << countNumberswith4(n) << endl;
return 0;
}
class GFG {
// Function to check if a number contains digit 4
static boolean containsFour(int n) {
while (n > 0) {
// If digit is 4, return true
if (n % 10 == 4) {
return true;
}
// Move to next digit
n /= 10;
}
return false;
}
static int countNumberswith4(int n) {
int count = 0;
for (int i = 1; i <= n; i++) {
// Increment count if i contains digit 4
if (containsFour(i)) {
count++;
}
}
return count;
}
public static void main(String[] args) {
int n = 50;
System.out.println(countNumberswith4(n));
}
}
# Function to check if a number contains digit 4
def containsFour(n):
while n > 0:
# If digit is 4, return true
if n % 10 == 4:
return True
# Move to next digit
n //= 10
return False
def countNumberswith4(n):
count = 0
for i in range(1, n + 1):
# Increment count if i contains digit 4
if containsFour(i):
count += 1
return count
if __name__ == "__main__":
n = 50
print(countNumberswith4(n))
using System;
class GFG
{
// Function to check if a number contains digit 4
static bool containsFour(int n)
{
while (n > 0)
{
// If digit is 4, return true
if (n % 10 == 4)
{
return true;
}
// Move to next digit
n /= 10;
}
return false;
}
static int countNumberswith4(int n)
{
int count = 0;
for (int i = 1; i <= n; i++)
{
// Increment count if i contains digit 4
if (containsFour(i))
{
count++;
}
}
return count;
}
static void Main()
{
int n = 50;
Console.WriteLine(countNumberswith4(n));
}
}
// Function to check if a number contains digit 4
function containsFour(n) {
while (n > 0) {
// If digit is 4, return true
if (n % 10 === 4) {
return true;
}
// Move to next digit
n = Math.floor(n / 10);
}
return false;
}
function countNumberswith4(n) {
let count = 0;
for (let i = 1; i <= n; i++) {
// Increment count if i contains digit 4
if (containsFour(i)) {
count++;
}
}
return count;
}
// Driver code
let n = 50;
console.log(countNumberswith4(n));
Output
14
[Expected Approach] Using Mathematics - O(log n) Time and O(log n) Space
The idea is to use a complete ranges instead of checking every number individually.
Let countArr[i] represent the number of integers from 1 to 10^i - 1 that contain the digit 4.
For example:
- For one-digit numbers, only 4 contains the digit 4: countArr[1] = 1
- For two-digit numbers: countArr[2] = 1 * 9 + 10 = 19
- For three-digit numbers: countArr[3] = 19 * 9 + 100 = 271
Therefore, the general recurrence is: countArr[i] = countArr[i - 1] * 9 + 10^(i - 1)
Here, countArr[i - 1] * 9 counts the numbers containing 4 in the blocks whose first digit is not 4, while 10^(i - 1) accounts for the block whose first digit is 4.
For a given n, find:
- numDigits = number of digits in n minus 1
- powerTen = 10^numDigits
- msd = most significant digit of n
- remainder = digits after the MSD
The value of msd determines how the block containing 4 is handled.
Case 1: MSD < 4
Consider: n = 328
- The complete blocks before 300 are: 000 - 099, 100 - 199, and 200 - 299.
- There are 3 such blocks, and each contributes countArr[2] numbers containing 4.
- The remaining range is 300 - 328, which can be handled recursively using 28.
Therefore: count = msd * countArr[numDigits] + countNumberswith4(remainder)
Case 2: MSD = 4
Consider: n = 428
- The complete blocks before 400 are: 000 - 099, 100 - 199, 200 - 299 and 300 - 399
- There are 4 complete blocks, contributing: 4 * countArr[2]
- Now, from 400 to 428, every number contains 4. The number of such numbers is: 428 - 400 + 1 = 29
Therefore: count = msd * countArr[numDigits] + remainder + 1
Case 3: MSD > 4
Consider: n = 728
- The complete blocks before 700, excluding the 400 - 499 block, contribute: (msd - 1) × countArr[2]
- The block 400 - 499 is special because every number in it contains 4. Its contribution is: powerTen = 100
- Finally, the remaining range 700 - 728 is handled recursively using 28.
Therefore: count = (msd - 1) * countArr[numDigits] + powerTen + countNumberswith4(remainder)
#include <bits/stdc++.h>
using namespace std;
int countNumberswith4(int n) {
// Base case
if (n < 4) {
return 0;
}
// If n is a one-digit number
if (n < 10) {
return 1;
}
// numDigits = number of digits minus one in n
// For 328, numDigits is 2
int numDigits = log10(n);
// Vector to store precomputed counts
vector<int> countArr(numDigits + 1, 0);
// Initializing base cases
countArr[1] = 1;
// Computing count of numbers from 1 to 10^d - 1
for (int i = 2; i <= numDigits; i++) {
countArr[i] = countArr[i - 1] * 9 + ceil(pow(10, i - 1));
}
// Computing 10^numDigits
int powerTen = ceil(pow(10, numDigits));
// Most significant digit (msd) of n
int msd = n / powerTen;
// If MSD is 4
if (msd == 4) {
return (msd) * countArr[numDigits] + (n % powerTen) + 1;
}
// If MSD > 4
if (msd > 4) {
return (msd - 1) * countArr[numDigits] + powerTen
+ countNumberswith4(n % powerTen);
}
// If MSD < 4
return (msd) * countArr[numDigits]
+ countNumberswith4(n % powerTen);
}
int main() {
int n = 50;
cout << countNumberswith4(n) << endl;
return 0;
}
class GFG {
static int countNumberswith4(int n) {
// Base case
if (n < 4) {
return 0;
}
// If n is a one-digit number
if (n < 10) {
return 1;
}
// numDigits = number of digits minus one in n
// For 328, numDigits is 2
int numDigits = (int) Math.log10(n);
// Vector to store precomputed counts
int[] countArr = new int[numDigits + 1];
// Initializing base cases
countArr[1] = 1;
// Computing count of numbers from 1 to 10^d - 1
for (int i = 2; i <= numDigits; i++) {
countArr[i] = countArr[i - 1] * 9
+ (int) Math.ceil(Math.pow(10, i - 1));
}
// Computing 10^numDigits
int powerTen = (int) Math.ceil(Math.pow(10, numDigits));
// Most significant digit (msd) of n
int msd = n / powerTen;
// If MSD is 4
if (msd == 4) {
return msd * countArr[numDigits] + (n % powerTen) + 1;
}
// If MSD > 4
if (msd > 4) {
return (msd - 1) * countArr[numDigits] + powerTen
+ countNumberswith4(n % powerTen);
}
// If MSD < 4
return msd * countArr[numDigits]
+ countNumberswith4(n % powerTen);
}
public static void main(String[] args) {
int n = 50;
System.out.println(countNumberswith4(n));
}
}
import math
def countNumberswith4(n):
# Base case
if n < 4:
return 0
# If n is a one-digit number
if n < 10:
return 1
# numDigits = number of digits minus one in n
# For 328, numDigits is 2
numDigits = int(math.log10(n))
# List to store precomputed counts
countArr = [0] * (numDigits + 1)
# Initializing base cases
countArr[1] = 1
# Computing count of numbers from 1 to 10^d - 1
for i in range(2, numDigits + 1):
countArr[i] = countArr[i - 1] * 9 + math.ceil(math.pow(10, i - 1))
# Computing 10^numDigits
powerTen = math.ceil(math.pow(10, numDigits))
# Most significant digit (msd) of n
msd = n // powerTen
# If MSD is 4
if msd == 4:
return (msd) * countArr[numDigits] + (n % powerTen) + 1
# If MSD > 4
if msd > 4:
return (msd - 1) * countArr[numDigits] + powerTen \
+ countNumberswith4(n % powerTen)
# If MSD < 4
return (msd) * countArr[numDigits] \
+ countNumberswith4(n % powerTen)
if __name__ == "__main__":
n = 50
print(countNumberswith4(n))
using System;
using System.Collections.Generic;
class GFG {
static int countNumberswith4(int n)
{
// Base case
if (n < 4) {
return 0;
}
// If n is a one-digit number
if (n < 10) {
return 1;
}
// numDigits = number of digits minus one in n
// For 328, numDigits is 2
int numDigits = (int)Math.Log10(n);
// Array to store precomputed counts
int[] countArr = new int[numDigits + 1];
// Initializing base cases
countArr[1] = 1;
// Computing count of numbers from 1 to 10^d - 1
for (int i = 2; i <= numDigits; i++) {
countArr[i] = countArr[i - 1] * 9
+ (int)Math.Pow(10, i - 1);
}
// Computing 10^numDigits
int powerTen = (int)Math.Pow(10, numDigits);
// Most significant digit (msd) of n
int msd = n / powerTen;
// If MSD is 4
if (msd == 4) {
return (msd)*countArr[numDigits]
+ (n % powerTen) + 1;
}
// If MSD > 4
if (msd > 4) {
return (msd - 1) * countArr[numDigits]
+ powerTen
+ countNumberswith4(n % powerTen);
}
// If MSD < 4
return (msd)*countArr[numDigits]
+ countNumberswith4(n % powerTen);
}
public static void Main()
{
int n = 50;
Console.WriteLine(countNumberswith4(n));
}
}
function countNumberswith4(n) {
// Base case
if (n < 4) {
return 0;
}
// If n is a one-digit number
if (n < 10) {
return 1;
}
// numDigits = number of digits minus one in n
// For 328, numDigits is 2
let numDigits = Math.floor(Math.log10(n));
// Array to store precomputed counts
let countArr = new Array(numDigits + 1).fill(0);
// Initializing base cases
countArr[1] = 1;
// Computing count of numbers from 1 to 10^d - 1
for (let i = 2; i <= numDigits; i++) {
countArr[i] = countArr[i - 1] * 9
+ Math.ceil(Math.pow(10, i - 1));
}
// Computing 10^numDigits
let powerTen = Math.ceil(Math.pow(10, numDigits));
// Most significant digit (msd) of n
let msd = Math.floor(n / powerTen);
// If MSD is 4
if (msd == 4) {
return (msd) * countArr[numDigits] + (n % powerTen) + 1;
}
// If MSD > 4
if (msd > 4) {
return (msd - 1) * countArr[numDigits] + powerTen
+ countNumberswith4(n % powerTen);
}
// If MSD < 4
return (msd) * countArr[numDigits]
+ countNumberswith4(n % powerTen);
}
// Driver code
let n = 50;
console.log(countNumberswith4(n));
Output
14