对数组执行操作使平方和最大
难度:
标签:
题目描述
You are given a 0-indexed integer array nums
and a positive integer k
.
You can do the following operation on the array any number of times:
- Choose any two distinct indices
i
andj
and simultaneously update the values ofnums[i]
to(nums[i] AND nums[j])
andnums[j]
to(nums[i] OR nums[j])
. Here,OR
denotes the bitwiseOR
operation, andAND
denotes the bitwiseAND
operation.
You have to choose k
elements from the final array and calculate the sum of their squares.
Return the maximum sum of squares you can achieve.
Since the answer can be very large, return it modulo 109 + 7
.
Example 1:
Input: nums = [2,6,5,8], k = 2 Output: 261 Explanation: We can do the following operations on the array: - Choose i = 0 and j = 3, then change nums[0] to (2 AND 8) = 0 and nums[3] to (2 OR 8) = 10. The resulting array is nums = [0,6,5,10]. - Choose i = 2 and j = 3, then change nums[2] to (5 AND 10) = 0 and nums[3] to (5 OR 10) = 15. The resulting array is nums = [0,6,0,15]. We can choose the elements 15 and 6 from the final array. The sum of squares is 152 + 62 = 261. It can be shown that this is the maximum value we can get.
Example 2:
Input: nums = [4,5,4,7], k = 3 Output: 90 Explanation: We do not need to apply any operations. We can choose the elements 7, 5, and 4 with a sum of squares: 72 + 52 + 42 = 90. It can be shown that this is the maximum value we can get.
Constraints:
1 <= k <= nums.length <= 105
1 <= nums[i] <= 109
代码结果
运行时间: 1189 ms, 内存: 29.6 MB
/*
* Problem: Given an array of integers nums and an integer k, you can perform an operation any number of times to modify the array.
* You can choose two different indices i and j, then update nums[i] to (nums[i] AND nums[j]) and nums[j] to (nums[i] OR nums[j]).
* The goal is to maximize the sum of squares of k elements from the final array. Return the result modulo 10^9 + 7.
*/
import java.util.Arrays;
public class Solution {
public int maxSumOfSquares(int[] nums, int k) {
// First, sort the array in descending order using Streams
nums = Arrays.stream(nums).boxed()
.sorted((a, b) -> b - a)
.mapToInt(i -> i)
.toArray();
// Calculate the sum of squares of the first k elements
long sum = Arrays.stream(nums)
.limit(k)
.mapToLong(num -> (long) num * num)
.sum();
// Return the result modulo 10^9 + 7
return (int) (sum % 1000000007);
}
}
解释
方法:
该题解首先获取数组中最大数的二进制位长度。然后,创建一个数组 f,其长度为最大二进制位长度,用于统计 nums 中每个比特位上 1 的个数。随后,采用贪心算法尝试构造最大的数。具体来说,从最高位到最低位,如果某个位上有 1,就将该位加到构造的数 x 中,并更新计数。这样构建的 x 将会是局部最大的可能值。重复这一过程 k 次或直到无法构造更多的非零数 x。每次迭代中计算 x 的平方,并累加到结果 ans 中。最终,返回的 ans 就是 k 个数的平方和最大的可能值。
时间复杂度:
O((n+k)*m)
空间复杂度:
O(m)
代码细节讲解
🦆
题解中提到的操作`选择两个互不相同的下标 i 和 j ,同时将 nums[i] 更新为 (nums[i] AND nums[j]) 且将 nums[j] 更新为 (nums[i] OR nums[j])`,这种操作如何保证最终能够形成k个最大的数值?
▷🦆
在提到的贪心算法中,`从最高位到最低位`的构造方式,为什么是从最高位开始,较低位的1的数量是否会影响这种构造方式的有效性?
▷🦆
题解中的数组f用于存储每个位上1的个数,这种方法对于非常大的nums数组是否仍然有效,有没有可能造成计算上的延迟或内存不足?
▷