1 题目
1295. 统计位数为偶数的数字
给你一个整数数组 nums,请你返回其中位数为 偶数 的数字的个数。
示例 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
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-numbers-with-even-number-of-digits
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2 分析
- 求整数位数(可求!有方法!)
- 位数是不是偶数
求整数位数的方法
- 直接使用整数求长度
- 转换为字符串求长度
提示:
1 <= nums.length <= 500
1 <= nums[i] <= 10^5
这是关键信息。
- 数组个数最多500
- 每个元素最多10000
备注:此处,官网的输入测试用例居然有
100000
,这应该是bug,不用理会。
关注限定条件!
- 数少的,甚至可以手算
- 数较多的,需要一般算法
- 数量极大的,需要高级算法
3 代码
3.1 按照int求长度
极其简单!
假定传入int n
C++代码:
while(n != 0){count++;n /= 10;
}
适用范围:所有整数(正数,0,负数)
3.2 转换为字符串求长度
先将int转换为字符串,然后直接求出长度,看看是不是偶数,一个表达式到位,这里只求长度。
Java代码:
int n = -100;
System.out.println(String.valueOf(n).length());
适用范围:自然数(正数数,0)
负数不行!因为有“-”,Because it has a minus sign.
3.3 题解
3.3.1 直接求(若可以输入0,就会有问题)
框架思维
public int findNumbers(int[] nums) {int result = 0; // 我要得到的结果存在这里return result; // 返回这个结果}
Java
public int findNumbers(int[] nums) {int result = 0;int digitCount = 0;for(int i:nums){digitCount = 0;while(i != 0){digitCount++;i /= 10;}if(digitCount % 2 == 0)result++;}return result;}
面向对象:Every element in the array ‘nums’.
核心结构:求int的位数
思路框架
- 遍历每一个元素
- 求整数位数
- 看看是不是偶数
不管数据有多大,只要是整数,都可以(除了0)!但是数据太大的话,就太慢了。
- 时间复杂度 O(n2)
- 空间复杂度O(1)
额外注意:0会报错,0是1位数,当前算法会判断0是0位数,就死了,特殊情况单独处理即可。
3.3.2 转字符串
Java
public int findNumbers(int[] nums) {int count = 0;int result = 0;for(int i:nums){if(String.valueOf(i).length() % 2 == 0)result++;}return result;}
对于大规模数据,好用!
需要注意负数的处理,取其绝对值再做。
- 时间复杂度 O(n)
- 空间复杂度O(1)
3.4 特殊法题解:根据限定条件求
public int findNumbers(int[] nums) {int result = 0;for(int i:nums){if((i >= 10 && i <= 99) || (i >= 1000 && i <= 9999))result++;}return result;}
此处在力扣会报错,100000
不对,但是,这与题目不符,应该是测试用例库错误!不用理会不重要。
当给定一些特殊的限定范围,可以使用特殊法,但是不具备参考价值,没有通用性。
3.5 方法比较分析 与 数据限定范围重要性
根据每个方法的分析,可以知道数据范围的重要性,范围不同,算法就不同。
本题面向数组内的元组,因此遍历肯定是要的,for或者for each。
别的没啥好说的。
4 收获
4.1 一定要关注限定范围,你处于真实世界!
4.2 尽可能一次提交正确,不要使用提交试错,比赛也不允许
4.2 面向对象的算法设计 & 清零思维
很难的题目都是由小题目构成
我们需要抽丝剥茧,找到我们所面对的那个对象的算法,只关注它,然后再扩大一层,看看需不需要清零操作,类似往外推。
自外而内,自内而外。
4.3 框架思维
框架一:方法结果及其返回
我想象我要得到这个结果,我把它存在这里,然后返回,之后,我再看看我该怎么做。
public int findNumbers(int[] nums) {int result = 0; // 我要得到的结果存在这里return result; // 返回这个结果}
**要灵活使用!**例如特殊情况,直接返回就可以,不要再赋值了……
框架二:遍历数组元素
for(int i:nums){}
for(int i = 0;i < nums.length();i++){}
框架三:求正数位数
框架四:特殊情况单独列出
4.4 追求逻辑上的简洁,而不是代码上的简洁
5 第二掌 2020.06.11
重新做一遍,新的感悟
- 偶数的定义:
整数 % 2 == 0;
- 求整数为数的循环法,0要单独算
- 求字符串长度,使用了两个类方法