描述
在牛牛面前放着nn个数,这些数字既有奇数也有偶数,只不过牛牛对奇数情有独钟,他特别想让这些数都变成奇数。
现在牛牛获得了一种能力,他可以执行一种操作:每次选中一个偶数,然后把这些数中与该数相等的数都除以2,例如现在有一个数组为[2,2,3][2,2,3],那么牛牛可以执行一次操作,使得这个数组变为[1,1,3][1,1,3]。
牛牛现在想知道,对于任意的nn个数,他最少需要操作多少次,使得这些数都变成奇数?
示例1
输入: 3,[2,2,3] 返回值: 1 说明: 只需做一次操作,会将其中的偶数2都变成1,满足了所有的数都是奇数的要求。
示例2
输入: 3,[1,3,7] 返回值: 0 说明: 不需要做任何操作,因为所有的数原本就是奇数。
思路
这道题其实就是 找到所有的偶数,然后选中一个偶数除以 2, 并且相同的偶数都会执行除以2的操作。然后统计操作的次数。
其实咱们也不用非得所有数都除以2,每个数除以 2 之后给记录下来,以后碰到这个 数之后就跳过不用处理即可。

如上图:
- 开始遍历数组,遇到第一个偶数先放入一个去重集合中,然后对该偶数除以2,如果还是偶数的话,在放入集合中在除以2,直到变为奇数为止。
- 继续遍历数组,如果遇到偶数并且在集合中就跳过,否则继续执行上面操作。
- 每次除以2时就将次数 + 1.
AC 代码
public int oddNumber (int n, int[] a) {
// write code here
if (a == null || a.length < 1) {
return 0;
}
// 去重集合
Set<Integer> set = new HashSet<>();
// 总的次数
int count = 0;
// 遍历数组
for (int i = 0; i < a.length; i ++) {
// 如果时 偶数 并且不再集合中
while ((a[i] & 1) == 0 && !set.contains(a[i])) {
// 先加入去重集合
set.add(a[i]);
// 除以2
a[i] /= 2;
// 次数 ++
count ++;
}
}
return count;
} - 时间复杂度:O(N), N 为数组长度,因为每个元素都要遍历一次。
- 空间复杂度:O(N), 最坏的情况时每个元素都存储在集合中。
最后
大家有兴趣可以来我的牛客博客中看看其他内容,兴许对你有所帮助。

京公网安备 11010502036488号