2595-奇偶位数

Raphael Liu Lv10

给你一个 整数 n

even 表示在 n 的二进制形式(下标从 0 开始)中值为 1 的偶数下标的个数。

odd 表示在 n 的二进制形式(下标从 0 开始)中值为 1 的奇数下标的个数。

返回整数数组 __answer __ ,其中 __answer = [even, odd]

示例 1:

**输入:** n = 17
**输出:** [2,0]
**解释:** 17 的二进制形式是 10001 。 
下标 0 和 下标 4 对应的值为 1 。 
共有 2 个偶数下标,0 个奇数下标。

示例 2:

**输入:** n = 2
**输出:** [0,1]
**解释:** 2 的二进制形式是 10 。 
下标 1 对应的值为 1 。 
共有 0 个偶数下标,1 个奇数下标。

提示:

  • 1 <= n <= 1000

视频讲解

【周赛 337】

方法一:二进制基本操作

不断取最低位,然后右移,直到等于 0 为止,这样可以取到每个比特位。

[sol1-Python3]
1
2
3
4
5
6
7
8
9
class Solution:
def evenOddBit(self, n: int) -> List[int]:
ans = [0, 0]
i = 0
while n:
ans[i] += n & 1
n >>= 1
i ^= 1
return ans
[sol1-Java]
1
2
3
4
5
6
7
8
class Solution {
public int[] evenOddBit(int n) {
var ans = new int[2];
for (int i = 0; n > 0; i ^= 1, n >>= 1)
ans[i] += n & 1;
return ans;
}
}
[sol1-C++]
1
2
3
4
5
6
7
8
9
class Solution {
public:
vector<int> evenOddBit(int n) {
vector<int> ans(2);
for (int i = 0; n; i ^= 1, n >>= 1)
ans[i] += n & 1;
return ans;
}
};
[sol1-Go]
1
2
3
4
5
6
7
8
func evenOddBit(n int) []int {
ans := make([]int, 2)
for i := 0; n > 0; i ^= 1 {
ans[i] += n & 1
n >>= 1
}
return ans
}

复杂度分析

  • 时间复杂度:O(\log n)。
  • 空间复杂度:O(1)。仅用到若干额外变量。

方法二:位掩码 + 库函数

利用位掩码 0x55555555(二进制的 010101\cdots),取出偶数下标比特和奇数下标比特,分别用库函数统计 1 的个数。

本题由于 n 范围比较小,取 0x5555 作为位掩码。

[sol2-Python3]
1
2
3
4
class Solution:
def evenOddBit(self, n: int) -> List[int]:
MASK = 0x5555
return [(n & MASK).bit_count(), (n & (MASK >> 1)).bit_count()]
[sol2-Java]
1
2
3
4
5
6
class Solution {
public int[] evenOddBit(int n) {
final int MASK = 0x5555;
return new int[]{Integer.bitCount(n & MASK), Integer.bitCount(n & (MASK >> 1))};
}
}
[sol2-C++]
1
2
3
4
5
6
7
class Solution {
public:
vector<int> evenOddBit(int n) {
const int MASK = 0x5555;
return {__builtin_popcount(n & MASK), __builtin_popcount(n & (MASK >> 1))};
}
};
[sol2-Go]
1
2
3
4
func evenOddBit(n int) []int {
const mask = 0x5555
return []int{bits.OnesCount16(uint16(n & mask)), bits.OnesCount16(uint16(n & (mask >> 1)))}
}

复杂度分析

  • 时间复杂度:O(1)。
  • 空间复杂度:O(1)。仅用到若干额外变量。
 Comments