Count Even Numbers
给定一个非空整数列表 nums,返回其中偶数的个数。一个数能被 2 整除且没有余数时,就是偶数,其中包括 0 和 -4 这样的负数。
函数
- numsinteger-array
- 要检查的整数列表
- 返回值integer
- nums 中偶数值的数量
约束条件
1 ≤ nums.length ≤ 5000-109 ≤ nums[i] ≤ 109
示例
- 输入
- nums = [3, 8, 12, 5, 6]
- 输出
- 3
- 解释
8、12和6都能被2整除,没有余数;3和5则不能。答案是3。
- 输入
- nums = [-4, -3, 0, 7]
- 输出
- 2
- 解释
-4 = 2 × (-2)和0 = 2 × 0,所以它们都是偶数。-3和7是奇数,数量是2。
- 输入
- nums = [1, 9, 15]
- 输出
- 0
- 解释
1、9和15都是奇数,所以答案是0。
进阶
你会收到很多问题:索引 l 和索引 r 之间有多少个偶数?遍历一次 nums 后,你能否在 O(1) 时间内回答每个问题?
提示
逐个打开提示,每个都会多透露一点。
偶数除以
2后还剩下什么?当且仅当
x % 2等于0时,值x才是偶数。注意:对于负奇数,有些语言得到的余数是-1,而不是1。将计数器设为
0,每个值读取一次,并在除以2的余数为0时加上1。
题解
检查每个值,并统计除以 2 后余数为 0 的值。将余数与 0 比较,而不是用 1 判断是否为奇数,这样负数也能正确处理。
收集偶数值,然后对它们计数
思路
用筛选器选出偶数值,然后返回结果的长度。对于 [3, 8, 12, 5, 6],筛选后的列表是 [8, 12, 6],所以答案是 3。
时间复杂度是 O(n),但新列表会占用 O(n) 的内存,最多存储 5000 个值,而你只读取一次它的长度。
算法
- 创建一个新列表,其中包含
nums中所有满足x % 2 == 0的x。 - 返回该列表的长度。
def countEvens(nums):
evens = [x for x in nums if x % 2 == 0]
return len(evens)使用计数器进行计数
思路
使用计数器而不是列表,并对每个满足 x % 2 == 0 的值加 1。偶数无论正负,余数都是 0,所以在任何语言中,这个测试对 -4 和 0 都成立。判断奇数的测试 x % 2 == 1 则不成立:在 C、Java、JavaScript 和大多数类 C 语言中,余数的符号与数字相同,因此 -3 % 2 的结果是 -1。
只遍历一次,只使用一个整数:时间复杂度为 O(n),空间复杂度为 O(1)。
算法
- 将
count设为0。 - 遍历
nums中的每个值x。 - 如果
x % 2 == 0,就将count增加1。 - 循环结束后,返回
count。
def countEvens(nums):
count = 0
for x in nums:
if x % 2 == 0: # 0 also works for negatives, where the remainder can be -1
count += 1
return count
易错点和边界情况
- 通过
x % 2 == 1统计奇数值,再用总长度减去这个数量。在类似 C 的语言中,-3 % 2的结果是-1,所以[-3]返回 1,而不是 0。 - 把
0当作既非偶数也非奇数。0 = 2 × 0,所以[0]返回1。 - 把位测试写成
x & 1 == 0。在 C、C++ 和 JavaScript 中,==的优先级高于&,所以它的意思是x & (1 == 0),结果始终是0,因此什么也统计不到。应写成(x & 1) == 0。
常见问题3
如何在代码中检查一个数字是否为偶数?
测试除以 2 后的余数是否为零:x % 2 == 0。对于正数、负数和零,这种方法都有效,即使在 -3 % 2 的结果为 -1 的语言中也适用。你也可以用 (x & 1) == 0 检查最低位。
0 是偶数吗?
是的。0 除以 2 等于 0,没有余数,因此符合偶数的定义。它也位于奇数 -1 和 1 之间,偶数应当处于这个位置。
统计数组中偶数的时间复杂度是多少?
使用计数器遍历一次需要 O(n) 时间和 O(1) 额外空间。必须检查每个值,因此没有比 O(n) 更快的方法。
相似题目
运用相同思路的题目。做两三道,才能真正掌握一种模式。
def countEvens(nums):
# 在这里编写代码测试 #1
测试 #2
测试 #3
参数
nums = [3, 8, 12, 5, 6]
预期输出
3