文章

[LeetCode] 每日一题 1295. 统计位数为偶数的数字(简单题)

题目描述

给你一个整数数组 nums,请你返回其中包含 偶数 个数位的数字的个数。

题目链接

https://leetcode.cn/problems/find-numbers-with-even-number-of-digits

示例输入

示例 1

输入:nums = [12,345,2,6,7896]
输出:2
解释:
12 是 2 位数字(位数为偶数) 
345 是 3 位数字(位数为奇数)  
2 是 1 位数字(位数为奇数) 
6 是 1 位数字 位数为奇数) 
7896 是 4 位数字(位数为偶数)  
因此只有 12 和 7896 是位数为偶数的数字

示例 2

输入:nums = [555,901,482,1771]
输出:1 
解释: 
只有 1771 是位数为偶数的数字。

提示

  • 1 <= nums.length <= 500

  • 1 <= nums[i] <= 10^5

解题思路

这题可以说是纯纯的入门题,只要统计每个数字的位数,再判断是否为偶数即可。最直接的写法是将数字转成字符串,判断字符串长度是否为偶数。但考虑到题目中 1 <= nums[i] <= 10^5,其实我们可以进一步优化,用范围判断代替字符串转换。

具体来说,只有位数为 2、4、6 的数字是我们要计数的目标。我们就可以按数值范围进行过滤,比如:

  • 小于 10 的数字是 1 位;

  • 10 到 99 是 2 位,符合要求;

  • 100 到 999 是 3 位,不符合;

  • 1000 到 9999 是 4 位,符合;

  • 10000 到 99999 是 5 位,不符合;

  • 正好 100000 是 6 位,符合要求。

基于这个逻辑写判断函数,比字符串处理更高效,而且看起来也更清晰。

代码实现

class Solution {
    public int findNumbers(int[] nums) {
        int count = 0;
        for (int num : nums) {
            //if (isEventDigit1(num)) {
            if (isEvenDigit2(num)) {
                count++;
            }
        }
        return count;
    }

    private boolean isEventDigit1(int num) {
        return Integer.toString(num).length() % 2 == 0;
    }

    private boolean isEvenDigit2(int num) {
        if (num < 10) {
            return false;
        }
        if (num < 100) {
            return true;
        }
        if (num < 1000) {
            return false;
        }
        if (num < 10000) {
            return true;
        }
        if (num < 100000) {
            return false;
        }
        return true;
    }
}

复杂度分析

  • 时间复杂度:O(n) 🕒

    • n 是数组长度,每个数处理一次

  • 空间复杂度:O(1) 💾

    • 只用了常量级变量,无额外内存开销

总结

这题非常简单,算是典型的「热身题」。不过也让我思考到,在数值范围明确的场景下,其实很多字符串操作都可以被条件判断替代,不仅执行效率高,也能规避类型转换的开销。作为刷题训练,可以用来练习对位数与数值范围之间的对应关系,更加熟悉数字的结构

希望这篇分享能为你带来启发!如果你有任何问题或建议,欢迎在评论区留言,与我共同交流探讨。

License:  CC BY 4.0