LeetCode2595
LeetCode2595
目录
- 题目描述
- 示例
- 思路分析
- 代码段
- 代码逐行讲解
- 复杂度分析
- 总结的知识点
- 整合
- 总结
题目描述
给你一个整数 n
,请你返回一个长度为 2 的数组 ans
,其中:
ans[0]
是n
的二进制表示中偶数下标(从 0 开始)的 1 的个数。ans[1]
是n
的二进制表示中奇数下标的 1 的个数。
示例
示例 1
输入:
n = 17
输出:
[2, 0]
解释:
- 17 的二进制表示为
10001
。 - 偶数下标(0, 2, 4)中有 2 个 1。
- 奇数下标(1, 3)中有 0 个 1。
示例 2
输入:
n = 2
输出:
[0, 1]
解释:
- 2 的二进制表示为
10
。 - 偶数下标(0)中有 0 个 1。
- 奇数下标(1)中有 1 个 1。
思路分析
问题核心
我们需要统计整数 n
的二进制表示中,偶数下标和奇数下标的 1 的个数。
思路拆解
- 二进制遍历:
- 从最低位开始遍历
n
的二进制表示。
- 从最低位开始遍历
- 奇偶下标统计:
- 使用一个变量
i
表示当前下标,初始值为 0(偶数)。 - 每次遍历后,
i
在 0 和 1 之间切换,表示偶数下标和奇数下标。
- 使用一个变量
- 统计 1 的个数:
- 如果当前二进制位是 1,则根据
i
的值更新ans[0]
或ans[1]
。
- 如果当前二进制位是 1,则根据
- 右移操作:
- 每次遍历后,将
n
右移 1 位,继续处理下一个二进制位。
- 每次遍历后,将
代码段
class Solution {
public int[] evenOddBit(int n) {
int[] ans = new int[2];
for (int i = 0; n > 0; n >>= 1, i ^= 1) {
ans[i] += n & 1;
}
return ans;
}
}
代码逐行讲解
1. 初始化结果数组
int[] ans = new int[2];
ans
是一个长度为 2 的数组,ans[0]
用于存储偶数下标的 1 的个数,ans[1]
用于存储奇数下标的 1 的个数。
2. 遍历二进制位
for (int i = 0; n > 0; n >>= 1, i ^= 1) {
- 从最低位开始遍历
n
的二进制表示。 n >>= 1
:每次遍历后将n
右移 1 位。i ^= 1
:每次遍历后切换i
的值(0 和 1 之间切换),表示偶数下标和奇数下标。
3. 统计 1 的个数
ans[i] += n & 1;
n & 1
:获取当前二进制位的最低位。- 如果当前二进制位是 1,则根据
i
的值更新ans[0]
或ans[1]
。
4. 返回结果
return ans;
- 返回结果数组
ans
。
复杂度分析
时间复杂度
- 遍历
n
的二进制表示,时间复杂度为 O(log n)。
空间复杂度
- 只使用了常数级别的额外空间,因此空间复杂度为 O(1)。
总结的知识点
1. 二进制操作
- 使用右移操作
n >>= 1
遍历二进制位。 - 使用按位与操作
n & 1
获取最低位。
2. 奇偶下标切换
- 使用
i ^= 1
在 0 和 1 之间切换,表示偶数下标和奇数下标。
3. 数组操作
- 使用数组
ans
统计偶数下标和奇数下标的 1 的个数。
整合
class Solution {
public int[] evenOddBit(int n) {
int[] ans = new int[2]; // 初始化结果数组
for (int i = 0; n > 0; n >>= 1, i ^= 1) { // 遍历二进制位
ans[i] += n & 1; // 统计 1 的个数
}
return ans; // 返回结果
}
}
总结
通过遍历 n
的二进制表示,并利用奇偶下标切换统计 1 的个数。