Find Numbers with Even Number of Digits
EasyPrompt
Given an array nums of integers, return how many of them contain an even number of digits.
Example 1:
Input: nums = [12,345,2,6,7896]
Output: 2
Explanation:
12 contains 2 digits (even number of digits).
345 contains 3 digits (odd number of digits).
2 contains 1 digit (odd number of digits).
6 contains 1 digit (odd number of digits).
7896 contains 4 digits (even number of digits).
Therefore only 12 and 7896 contain an even number of digits.Example 2:
Input: nums = [555,901,482,1771]
Output: 1
Explanation:
Only 1771 contains an even number of digits.
Constraints:
1 <= nums.length <= 5001 <= nums[i] <= 105
Approaches
4 approaches with complexity analysis and trade-offs.
This approach iterates through each number in the input array. For each number, it converts it into a string and then checks the length of the string. If the length is an even number, a counter is incremented.
Algorithm
- Initialize a counter
evenDigitCountto 0. - Loop through each integer
numin thenumsarray. - Convert the integer
numto its string representation usingString.valueOf(num). - Find the length of the resulting string.
- Check if the length is divisible by 2 (i.e.,
length % 2 == 0). - If the length is even, increment
evenDigitCount. - After iterating through all the numbers, return
evenDigitCount.
Walkthrough
This method provides a straightforward way to solve the problem by leveraging built-in string functionalities. The core idea is that the number of digits in an integer is equivalent to the length of its string representation.
- We initialize a counter
evenDigitCountto 0. - We then loop through each integer
numin the inputnumsarray. - Inside the loop, we convert the current number
numto a string. For example, the integer123becomes the string"123". - We then get the length of this string. The length of
"123"is 3. - We check if this length is an even number using the modulo operator (
length % 2 == 0). - If the condition is true, we increment our
evenDigitCount. - After the loop has processed all numbers in the array, the
evenDigitCountholds the total count of numbers with an even number of digits, which we then return.
class Solution { public int findNumbers(int[] nums) { int evenDigitCount = 0; for (int num : nums) { // Convert the number to a string String s = String.valueOf(num); // Check if the length of the string is even if (s.length() % 2 == 0) { evenDigitCount++; } } return evenDigitCount; }}Complexity
Time
O(N * D), where N is the number of elements in the array and D is the maximum number of digits in a number. Converting a number with D digits to a string takes O(D) time. Given the problem constraints, D is small, so the complexity is often simplified to O(N).
Space
O(D), where D is the maximum number of digits in a number. This space is required to store the string representation of a number. Since the constraints limit numbers to 10^5, D is at most 6, making the space complexity effectively O(1).
Trade-offs
Pros
Simple to understand and implement.
The logic is very direct and easy to reason about.
Cons
Incurs the overhead of string conversion and memory allocation for each number, which is generally less efficient than purely mathematical approaches.
This method avoids string conversion by using a mathematical formula to find the number of digits. The number of digits in any positive integer n can be calculated as floor(log10(n)) + 1. We iterate through the array, calculate the number of digits for each number using this formula, and count how many have an even number of digits.
Algorithm
- Initialize a counter
evenDigitCountto 0. - Loop through each integer
numin thenumsarray. - Calculate the number of digits using the formula
(int)Math.floor(Math.log10(num)) + 1. - Check if the calculated number of digits is even.
- If it is, increment
evenDigitCount. - After the loop, return
evenDigitCount.
Walkthrough
Instead of converting numbers to strings, we can use a mathematical property to find the number of digits. The base-10 logarithm of a number can tell us its magnitude. Specifically, for any positive integer num, the number of digits is floor(log10(num)) + 1.
- We start with a counter
evenDigitCountset to 0. - We iterate through each
numin thenumsarray. - For each
num, we computeMath.log10(num). For example,log10(345)is approximately2.53. - We take the floor of this value (
floor(2.53)is2) and add 1, which gives us the correct digit count of 3. - We then check if this digit count is even.
- If it is, we increment
evenDigitCount. - Finally, we return the total count.
import java.lang.Math; class Solution { public int findNumbers(int[] nums) { int evenDigitCount = 0; for (int num : nums) { // Calculate number of digits using logarithm int digitCount = (int) Math.floor(Math.log10(num)) + 1; // Check if the digit count is even if (digitCount % 2 == 0) { evenDigitCount++; } } return evenDigitCount; }}Complexity
Time
O(N), where N is the number of elements in the array. We iterate through the array, and for each element, we perform a `log10` operation, which is generally considered a constant time operation for standard integer types.
Space
O(1). No extra space that scales with the input size is used. We only use a few variables for the counter and temporary calculations.
Trade-offs
Pros
Avoids the overhead of string conversion and object creation.
The code for calculating the number of digits is very concise.
Cons
Relies on floating-point arithmetic (
log10), which can be slower than pure integer arithmetic.Can have precision issues with extremely large numbers, although it's not a problem for the given constraints.
This approach counts the digits of each number by repeatedly dividing it by 10 until it becomes 0. This method uses only integer arithmetic, which is typically faster than string conversions or floating-point operations.
Algorithm
- Initialize a main counter
evenDigitCountto 0. - Iterate through each
numin thenumsarray. - For each
num, initialize a temporary digit counterdigitsto 0. - Use a
whileloop that continues as long as the current number is greater than 0. - Inside the loop, increment
digitsand update the number by dividing it by 10 (num = num / 10). - After the loop, check if
digitsis even. If so, incrementevenDigitCount. - Return
evenDigitCountafter checking all numbers.
Walkthrough
This is a highly efficient method that relies on basic integer arithmetic. To count the digits of a number, we can repeatedly perform integer division by 10 and count how many times we can do this before the number becomes 0.
- We initialize a counter
evenDigitCountto 0. - We loop through each
numin thenumsarray. - For each
num, we find its digit count. Let's take7896as an example:- Initialize
digits = 0. 7896 > 0:digitsbecomes 1,numbecomes 789.789 > 0:digitsbecomes 2,numbecomes 78.78 > 0:digitsbecomes 3,numbecomes 7.7 > 0:digitsbecomes 4,numbecomes 0.0 > 0is false, loop terminates. The digit count is 4.
- Initialize
- We then check if the final
digitscount (4 in this case) is even. If it is, we incrementevenDigitCount. - After processing all numbers, we return the final count.
class Solution { public int findNumbers(int[] nums) { int evenDigitCount = 0; for (int num : nums) { if (hasEvenDigits(num)) { evenDigitCount++; } } return evenDigitCount; } private boolean hasEvenDigits(int num) { int digitCount = 0; while (num > 0) { digitCount++; num /= 10; } return digitCount % 2 == 0; }}Complexity
Time
O(N * D), where N is the number of elements and D is the maximum number of digits. Since D is small and bounded by the constraint (max 6 digits for 10^5), the complexity is effectively O(N). This is generally faster in practice than the string and log approaches.
Space
O(1). We only use a few variables to store counts and perform calculations, requiring constant extra space.
Trade-offs
Pros
Very efficient as it only uses fast integer arithmetic operations.
Avoids the overhead of creating new objects (like strings) or using slower floating-point math.
Cons
The code is slightly more verbose than the logarithm-based approach.
This approach takes full advantage of the problem's constraints (1 <= nums[i] <= 10^5). Instead of calculating the number of digits for each number, we can directly check if a number falls within the specific ranges that correspond to an even number of digits.
Algorithm
- Initialize
count = 0. - For each
numinnums: - Check if
(10 <= num <= 99)OR(1000 <= num <= 9999)OR(num == 100000). - If the condition is true, increment
count. - Return
count.
Walkthrough
This is the most optimal solution because it leverages the given constraints to avoid any form of digit counting altogether. The constraints 1 <= nums[i] <= 10^5 mean that any number in the input array can have 1, 2, 3, 4, 5, or 6 digits.
We are only interested in numbers with an even number of digits. These are:
- Numbers with 2 digits: from 10 to 99.
- Numbers with 4 digits: from 1000 to 9999.
- Numbers with 6 digits: only 100000 is possible under the constraint.
We can combine these checks into a single if statement. For each number in the input array, we check if it satisfies any of these conditions. If it does, we increment a counter.
class Solution { public int findNumbers(int[] nums) { int count = 0; for (int num : nums) { if ((num >= 10 && num <= 99) || (num >= 1000 && num <= 9999) || num == 100000) { count++; } } return count; }}This method is extremely fast because it replaces loops (for division) or complex function calls (log10, String.valueOf) with a few simple integer comparisons.
Complexity
Time
O(N). We iterate through the array once. Each check inside the loop consists of a few simple integer comparisons, which takes constant time. This is the fastest possible approach.
Space
O(1). No extra space is needed beyond a single counter variable.
Trade-offs
Pros
The most efficient solution in terms of raw performance.
Extremely simple logic that avoids any form of iteration or complex math for digit counting.
Cons
The solution is hard-coded to the specific constraints of the problem (
1 <= nums[i] <= 10^5).If the constraints were to change, the
ifcondition would need to be manually updated, making it less general than other approaches.
Solutions
Solution
class Solution {public int findNumbers(int[] nums) { int ans = 0; for (int v : nums) { if (String.valueOf(v).length() % 2 == 0) { ++ans; } } return ans; }}/** * @param {number[]} nums * @return {number} */ var findNumbers = function ( nums,) { let ans = 0; for (const v of nums) { ans += String(v).length % 2 == 0; } return ans;};class Solution: def findNumbers( self, nums: List[int]) -> int: return sum(len(str(v)) % 2 == 0 for v in nums)class Solution {public: int findNumbers(vector<int> &nums) { int ans = 0; for (int &v : nums) { ans += to_string(v).size() % 2 == 0; } return ans; }};Video walkthrough
Newsletter
One sharp idea, every week
System design and interview prep — short enough to finish.
No spam. Unsubscribe anytime.
Practice
Same difficulty — related problems to reinforce the pattern.