leetcode
leetcode 2451 ~ 2500
计算 K 置位下标对应元素的和

计算 K 置位下标对应元素的和

难度:

标签:

题目描述

You are given a 0-indexed integer array nums and an integer k.

Return an integer that denotes the sum of elements in nums whose corresponding indices have exactly k set bits in their binary representation.

The set bits in an integer are the 1's present when it is written in binary.

  • For example, the binary representation of 21 is 10101, which has 3 set bits.

 

Example 1:

Input: nums = [5,10,1,5,2], k = 1
Output: 13
Explanation: The binary representation of the indices are: 
0 = 0002
1 = 0012
2 = 0102
3 = 0112
4 = 1002 
Indices 1, 2, and 4 have k = 1 set bits in their binary representation.
Hence, the answer is nums[1] + nums[2] + nums[4] = 13.

Example 2:

Input: nums = [4,3,2,1], k = 2
Output: 1
Explanation: The binary representation of the indices are:
0 = 002
1 = 012
2 = 102
3 = 112
Only index 3 has k = 2 set bits in its binary representation.
Hence, the answer is nums[3] = 1.

 

Constraints:

  • 1 <= nums.length <= 1000
  • 1 <= nums[i] <= 105
  • 0 <= k <= 10

代码结果

运行时间: 12 ms, 内存: 16.1 MB


// 思路:
// 1. 使用 Java Stream API 对 nums 数组进行处理。
// 2. 利用 IntStream.range 生成下标流。
// 3. 过滤出二进制表示中置位个数为 k 的下标。
// 4. 将这些下标对应的 nums 元素相加。

import java.util.stream.IntStream;

public class Solution {
    public int sumOfElementsWithKBits(int[] nums, int k) {
        return IntStream.range(0, nums.length) // 生成下标流
                .filter(i -> Integer.bitCount(i) == k) // 过滤出二进制表示中置位个数为 k 的下标
                .map(i -> nums[i]) // 将下标映射到对应的 nums 元素
                .sum(); // 将这些元素相加
    }
}

解释

方法:

此题解通过遍历数组 nums 的所有下标,对每个下标 i 转换为二进制形式,并计算二进制中1的个数。如果1的个数等于 k,就将对应的 nums[i] 加入到结果和中。最终返回这个求和结果。

时间复杂度:

O(n log n)

空间复杂度:

O(1)

代码细节讲解

🦆
为什么在计算下标的二进制中置位个数时选择使用 `bin(i).count('1')` 方法?是否有其他更高效的计算方法?
在计算下标的二进制中置位个数时,选择使用 `bin(i).count('1')` 方法是因为它直接转换下标为二进制字符串,然后计算字符串中'1'的出现次数,这样操作直观且容易理解。然而,这种方法不是最高效的,因为二进制字符串的生成与计数都有一定的开销。一个更高效的方法是使用 Brian Kernighan 算法来计算置位个数,该算法通过不断清除最低位的1(使用 `i &= i - 1` 操作),直到变量为0,其操作次数仅为置位的个数,这样可以显著提高计算效率。
🦆
题解提到如果 `bin(i).count('1') == k` 则进行累加,对于 k 的取值范围有什么特别的要求或限制吗?
对于 k 的取值,理论上 k 应该是一个非负整数。在实际应用中,k 的最小值应该是0(即没有任何置位),而最大值应不大于下标i能表示的最大位数的1的个数,即数组最大下标的二进制表示中的位数。如果 k 大于这个值,那么不会有任何下标的二进制中1的个数等于 k,因此函数将返回0。因此,这个算法对 k 有一个隐含的逻辑限制,即 0 <= k <= log2(数组最大下标)。
🦆
在实现中使用了循环遍历数组下标,如果数组长度极大,这种方法的性能如何?是否有可能通过预处理或其他技巧减少运算次数?
如果数组长度极大,直接遍历每个下标并检查其二进制中1的个数会导致较高的时间复杂度,特别是当数组长度达到数百万或更多时。一种可能的优化方法是预处理,即事先计算并存储所有可能下标的二进制中1的个数,这样在主循环中可以直接查询,从而避免在每次迭代中重复计算。此外,如果问题允许,可以考虑使用并行计算或其他硬件加速技术来提升处理速度。
🦆
解题类中的方法是否可以处理所有输入情况,例如 k 大于数组最大下标的位数情况,会返回什么结果?
解题类中的方法可以处理大多数输入情况,但如果 k 大于数组最大下标的位数,即 k 大于 log2(数组最大下标) 的情况,根据二进制的性质,不可能有任何下标的二进制中1的个数等于 k。因此,在这种情况下,循环内的条件 `bin(i).count('1') == k` 永远不会满足,所以函数将返回0。这种情况下,函数正确处理了输入,但结果将始终为0,这是符合预期的逻辑结果。

相关问题