Problem#
Write a function that takes a natural number as input and returns the number of digits the input has.
Constraint : don’t use any loops.
Examples#
Example 1#
1
2
3
Input: 123
Output: 3
Explanation: The number 123 has 3 digits: 1 , 2 , and 3.
Example 2#
1
2
3
Input: 1
Output: 1
Explanation: Single digit number has 1 digit.
Example 3#
1
2
3
Input: 1000
Output: 4
Explanation: The number 1000 has 4 digits: 1 , 0 , 0 , and 0.
Example 4#
1
2
3
Input: 999999
Output: 6
Explanation: The number 999999 has 6 digits.
Example 5#
1
2
3
Input: 0
Output: 1
Explanation: Zero is considered to have 1 digit.
Solution#
Method 1 - Logarithmic Calculation#
Intuition#
The key insight is that the number of digits in a positive integer n is floor(log₁₀(n)) + 1. This works because log₁₀(n) tells us the power of 10, and adding 1 gives us the digit count. For example, log₁₀(123) ≈ 2.09, so floor(2.09) + 1 = 3 digits. We need to handle the special case of 0 separately since log₁₀(0) is undefined.
Approach#
Handle Edge Case : Check if the number is 0, return 1 (since 0 has 1 digit)
Handle Negative Numbers : Take absolute value if dealing with negative numbers
Apply Logarithm : Calculate log₁₀(n) using natural logarithm: log₁₀(n) = ln(n) / ln(10)
Floor and Add One : Take floor of the result and add 1 to get digit count
Return Result : The calculated digit count
Code#
Cpp
Go
Java
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
public :
int countDigits(int n) {
if (n == 0 ) return 1 ;
// Handle negative numbers by taking absolute value
n = abs(n);
// Use logarithm: digits = floor(log10(n)) + 1
return static_cast < int > (floor(log10(n))) + 1 ;
}
// Alternative using natural logarithm
int countDigitsAlt (int n) {
if (n == 0 ) return 1 ;
n = abs(n);
// log10(n) = ln(n) / ln(10)
return static_cast < int > (floor(log(n) / log(10 ))) + 1 ;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
func CountDigits (n int ) int {
if n == 0 {
return 1
}
// Handle negative numbers
if n < 0 {
n = - n
}
// Use logarithm: digits = floor(log10(n)) + 1
return int(math .Floor (math .Log10 (float64(n )))) + 1
}
func CountDigitsAlt (n int ) int {
if n == 0 {
return 1
}
if n < 0 {
n = - n
}
// log10(n) = ln(n) / ln(10)
return int(math .Floor (math .Log (float64(n ))/ math .Log (10 ))) + 1
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Solution {
public int countDigits (int n) {
if (n == 0) return 1;
// Handle negative numbers
n = Math.abs (n);
// Use logarithm: digits = floor(log10(n)) + 1
return (int ) Math.floor (Math.log10 (n)) + 1;
}
public int countDigitsAlt (int n) {
if (n == 0) return 1;
n = Math.abs (n);
// log10(n) = ln(n) / ln(10)
return (int ) Math.floor (Math.log (n) / Math.log (10)) + 1;
}
// Version for long numbers
public int countDigitsLong (long n) {
if (n == 0) return 1;
n = Math.abs (n);
return (int ) Math.floor (Math.log10 (n)) + 1;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution :
def countDigits (self, n: int) -> int:
if n == 0 :
return 1
# Handle negative numbers
n = abs(n)
# Use logarithm: digits = floor(log10(n)) + 1
import math
return int(math. floor(math. log10(n))) + 1
def countDigitsAlt (self, n: int) -> int:
if n == 0 :
return 1
n = abs(n)
# log10(n) = ln(n) / ln(10)
import math
return int(math. floor(math. log(n) / math. log(10 ))) + 1
Complexity#
⏰ Time complexity: O(1)
as logarithm calculation is a constant time operation.
🧺 Space complexity: O(1)
as we only use a constant amount of extra space.
Method 2 - Recursive Division#
Intuition#
We can count digits recursively by dividing the number by 10 until it becomes 0. Each division represents removing one digit, so we count how many divisions we can perform. The base case is when the number becomes 0, and the recursive case is counting 1 plus the digits of n/10. This avoids loops while still achieving the counting goal.
Approach#
Base Case : If n is 0, return 1 (for the case when input is 0) or 0 (for recursive calls)
Handle Negative : Take absolute value to handle negative numbers
Recursive Call : Return 1 + countDigits(n/10) for the recursive division
Division Process : Each call reduces the number by one digit
Count Accumulation : Each recursive call adds 1 to the total count
Code#
Cpp
Go
Java
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class Solution {
public :
int countDigitsRecursive(int n) {
// Handle the edge case of 0
if (n == 0 ) return 1 ;
// Handle negative numbers
n = abs(n);
return countHelper (n);
}
private :
int countHelper(int n) {
// Base case: no more digits
if (n == 0 ) return 0 ;
// Recursive case: 1 digit + digits in n/10
return 1 + countHelper(n / 10 );
}
public :
// Alternative single function approach
int countDigitsRecursiveAlt(int n) {
if (n == 0 ) return 1 ; // Special case for input 0
n = abs(n); // Handle negative numbers
if (n < 10 ) return 1 ; // Single digit
return 1 + countDigitsRecursiveAlt(n / 10 );
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
func CountDigitsRecursive (n int ) int {
// Handle edge case of 0
if n == 0 {
return 1
}
// Handle negative numbers
if n < 0 {
n = - n
}
return countHelper (n )
}
func countHelper (n int ) int {
// Base case: no more digits
if n == 0 {
return 0
}
// Recursive case: 1 digit + digits in n/10
return 1 + countHelper (n / 10 )
}
func CountDigitsRecursiveAlt (n int ) int {
if n == 0 {
return 1 // Special case for input 0
}
if n < 0 {
n = - n // Handle negative numbers
}
if n < 10 {
return 1 // Single digit
}
return 1 + CountDigitsRecursiveAlt (n / 10 )
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class Solution {
public int countDigitsRecursive (int n) {
// Handle edge case of 0
if (n == 0) return 1;
// Handle negative numbers
n = Math.abs (n);
return countHelper(n);
}
private int countHelper (int n) {
// Base case: no more digits
if (n == 0) return 0;
// Recursive case: 1 digit + digits in n/10
return 1 + countHelper(n / 10);
}
public int countDigitsRecursiveAlt (int n) {
if (n == 0) return 1; // Special case for input 0
n = Math.abs (n); // Handle negative numbers
if (n < 10) return 1; // Single digit
return 1 + countDigitsRecursiveAlt(n / 10);
}
// Tail recursive version for better performance
public int countDigitsTailRecursive (int n) {
if (n == 0) return 1;
n = Math.abs (n);
return countTailHelper(n, 0);
}
private int countTailHelper (int n, int count) {
if (n == 0) return count;
return countTailHelper(n / 10, count + 1);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
class Solution :
def countDigitsRecursive (self, n: int) -> int:
# Handle edge case of 0
if n == 0 :
return 1
# Handle negative numbers
n = abs(n)
return self. _countHelper(n)
def _countHelper (self, n: int) -> int:
# Base case: no more digits
if n == 0 :
return 0
# Recursive case: 1 digit + digits in n//10
return 1 + self. _countHelper(n // 10 )
def countDigitsRecursiveAlt (self, n: int) -> int:
if n == 0 :
return 1 # Special case for input 0
n = abs(n) # Handle negative numbers
if n < 10 :
return 1 # Single digit
return 1 + self. countDigitsRecursiveAlt(n // 10 )
def countDigitsTailRecursive (self, n: int) -> int:
if n == 0 :
return 1
n = abs(n)
return self. _countTailHelper(n, 0 )
def _countTailHelper (self, n: int, count: int) -> int:
if n == 0 :
return count
return self. _countTailHelper(n // 10 , count + 1 )
Complexity#
⏰ Time complexity: O(log₁₀(n))
where n is the input number, as we make one recursive call for each digit.
🧺 Space complexity: O(log₁₀(n))
due to the recursive call stack depth, which is proportional to the number of digits.
Method 3 - String Conversion#
Intuition#
The simplest approach is to convert the number to a string and count its length. This leverages the built-in string conversion which handles all edge cases automatically. For negative numbers, we need to subtract 1 from the length to exclude the minus sign. This method is straightforward and handles all cases naturally without complex logic.
Approach#
Convert to String : Use built-in function to convert number to string representation
Handle Negative : Check if the number is negative and adjust accordingly
Count Characters : Get the length of the string
Adjust for Sign : Subtract 1 if the number was negative (to exclude minus sign)
Return Length : The string length represents the digit count
Code#
Cpp
Go
Java
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution {
public :
int countDigitsString(int n) {
string str = to_string(n);
// If negative, subtract 1 for the minus sign
return str.length() - (n < 0 ? 1 : 0 );
}
// Version using absolute value
int countDigitsStringAbs (int n) {
return to_string(abs(n)).length();
}
// Template version for different numeric types
template < typename T>
int countDigitsTemplate(T n) {
return to_string (abs(n)).length();
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
func CountDigitsString (n int ) int {
str := strconv .Itoa (n )
// If negative, subtract 1 for the minus sign
if n < 0 {
return len(str ) - 1
}
return len(str )
}
func CountDigitsStringAbs (n int ) int {
if n < 0 {
n = - n
}
return len(strconv .Itoa (n ))
}
func CountDigitsStringFmt (n int ) int {
str := fmt .Sprintf ("%d" , n )
if n < 0 {
return len(str ) - 1
}
return len(str )
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
public int countDigitsString (int n) {
String str = String.valueOf (n);
// If negative, subtract 1 for the minus sign
return str.length () - (n < 0 ? 1 : 0);
}
public int countDigitsStringAbs (int n) {
return String.valueOf (Math.abs (n)).length ();
}
// Version using StringBuilder for efficiency
public int countDigitsStringBuilder (int n) {
return new StringBuilder().append (Math.abs (n)).length ();
}
// Generic version for different numeric types
public < T extends Number> int countDigitsGeneric (T n) {
return String.valueOf (Math.abs (n.doubleValue ())).replace ("." , "" ).length ();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution :
def countDigitsString (self, n: int) -> int:
str_n = str(n)
# If negative, subtract 1 for the minus sign
return len(str_n) - (1 if n < 0 else 0 )
def countDigitsStringAbs (self, n: int) -> int:
return len(str(abs(n)))
def countDigitsStringFormat (self, n: int) -> int:
# Using f-string formatting
return len(f " { abs(n)} " )
def countDigitsStringOneliner (self, n: int) -> int:
return len(str(abs(n)))
Complexity#
⏰ Time complexity: O(log₁₀(n))
for the string conversion operation, which needs to process each digit.
🧺 Space complexity: O(log₁₀(n))
for storing the string representation of the number.