亚搏yabo(中国) 2026-05-19: 加多操作后最大按位与的驱逐。用go谈话, 已知一个整

2026-05-19:加多操作后最大按位与的驱逐。用go谈话,已知一个整数数组 nums,以及两个整数 k 和 m。你不错进行至多 k 次操作:每次操作你不错遴选数组中的某个位置 i,把 nums[i] 的值加多 1。
在最多作念完这 k 次操作之后,从数组里随性挑选出 m 个元素构成一个子集(子集大小固定为 m),对这 m 个元素作念按位与运算。你的目标是:让这个按位与的驱逐尽可能大。问最大的可能值是几许。
1
1
1
1
输入: nums = [3,1,2], k = 8, m = 2。
输出: 6。
讲明:
咱们需要一个大小为 m = 2 的子集。聘请下标 [0, 2]。
使用 3 次操作将 nums[0] = 3 加多到 6,并使用 4 次操作将 nums[2] = 2 加多到 6。
所有使用的操作次数为 7,不大于 k = 8。
这两个遴选的值变为 [6, 6],它们的按位与驱逐是 6,这是可能的最大值。
题目来独力扣3806。
算法实施忽闪步骤
一、问题核情意会
1. 操作规矩:最多把数组中元素所有加 k 次 1(不错给随性元素加)
2. 目标:操作完成后,选 m 个元素,让它们的按位与驱逐最大
3. 按位与特点:二进制位上所罕有该位都是 1,驱逐该位才是 1;只有有一个是 0,驱逐便是 0。因此咱们要从高位到低位,无餍尝试把每一位酿成 1。
二、第一步:预处分与规模判断
1. 排序数组:把 nums 从小到大排序,得到 [1,2,3]
2. 计较表面最大可能值:最大的数 + k/m(平平分派操作次数),这里 3+8/2=7,最终谜底一定不朝上 7
3. 特殊情况判断:查验最大的 m 个数是否一皆颠倒
• 本例最大 2 个数是 2、3,不竭顶,跳过特殊逻辑
三、核默算法:高位优先无餍构造谜底(按二进制位从高到低尝试)
二进制位数:表面最大值 7 是 3 位二进制(111),咱们从**最高位(第2位)→ 最低位(第0位)**递次尝试:
驱动谜底 ans = 0(二进制 000),目标是尽可能把每一位酿成 1。
第1轮:尝试斥地 最高位(第2位,值=4,二进制 100)
2. 计较把每个数酿成至少知足目标值需要的操作次数
• 规矩:只需要保证数的二进制高位和目标一致,计较最小加1次数
3. 排序操作次数:[1,2,3]
4. 选最小的 m=2 个次数乞降:1+2=3
5. 考证:3 ≤ 8(总操作数k)→ 该位不错设为1
ag最新app下载官方网站6. 更新谜底:ans = 4(二进制 100)
第2轮:尝试斥地 次高位(第1位,值=2,二进制 010)
1. 构造目标值:面前谜底(4) | 2 → 6(二进制 110)
2. 计较把每个数酿成至少知足 6 需要的操作次数
3. 排序操作次数:[3,4,5]
4. 选最小的 m=2 个次数乞降:3+4=7
5. 考证:7 ≤ 8 → 该位不错设为1
6. 更新谜底:ans = 6(二进制 110)
第3轮:尝试斥地 最低位(第0位,值=1,亚搏yabo(中国)二进制 001)
1. 构造目标值:面前谜底(6) | 1 → 7(二进制 111)
2. 计较把每个数酿成至少知足7需要的操作次数
3. 排序操作次数:[4,5,6]
4. 选最小的 m=2 个次数乞降:4+5=9
5. 考证:9 > 8(朝上总操作数)→ 该位不可设为1
6. 谜底保抓不变:ans 仍为 6
四、最终驱逐
统统位尝试兑现,最终最大按位与驱逐为 6,和题目示例齐备一致。
(操作决议:把3→6(3次)、2→6(4次),总7次≤8,两个数按位与=6)
时辰复杂度 & 特殊空间复杂度
1. 总时辰复杂度
O(W × n log n)
• W:二进制最大位数(固定值,约30~32位,因为数值上限1e9)
• n:数组长度
• 中枢耗时:每一轮都要对长度为n的操作次数数组排序(O(n log n)),共实施W轮
• 举座复杂度:线性对数级,齐备适配题目 n≤5e4 的为止
2. 总数外空间复杂度
O(n)
• 仅开辟了一个长度为n的数组ops,用于存储每个数的操作次数
• 其余变量都是常数级空间,不随输入领域变化
• 空间复杂度:线性级
回归
1. 中枢想路:高位无餍,从最高位到最低位递次尝试能否将该位设为1,能则保留,不可则跳过
2. 要道判断:计较让 m 个数知足目标值的最小操作次数总和,不朝上k则该位灵验
3. 时辰复杂度:O(32 × n log n),高效处分大数据量
4. 空间复杂度:O(n),仅使用一个援手数组存储操作次数
Go齐备代码如下:
package main
import (
"fmt"
"math/bits"
"slices"
)
func maximumAND(nums []int, k, m int) (ans int) {
slices.Sort(nums)
n := len(nums)
maxAns := nums[n-1] + k/m
if nums[n-m] == nums[n-1] { // 最大的 m 个数都颠倒
return maxAns
}
ops := make([]int, n) // 每个数的操作次数
maxWidth := bits.Len(uint(maxAns))
for bit := maxWidth - 1; bit >= 0; bit-- {
target := ans | 1
for i, x := range nums {
j := bits.Len(uint(target &^ x))
// j-1 是从高到低第一个 target 是 1 且 x 是 0 的比特位
// target = 10110
// x = 11010
// ^
// j-1
// x 二进制中的高于 j-1 的位不变,其余位增大到和 target 相同
// 上头的例子要把 010 酿成 110
mask := 1
ops[i] = target&mask - x&mask
}
// 无餍,取前 m 小的操作次数
slices.Sort(ops)
sum := 0
for _, x := range ops[:m] {
sum += x
}
if sum
ans = target // 谜底的 bit 位不错填 1
}
}
return
}
func main {
nums := []int{3, 1, 2}
k := 8
m := 2
result := maximumAND(nums, k, m)
fmt.Println(result)
}

Python齐备代码如下:
# -*-coding:utf-8-*-
def maximumAND(nums, k, m):
nums.sort
n = len(nums)
maxAns = nums[n-1] + k // m
# 最大的 m 个数都颠倒
if nums[n-m] == nums[n-1]:
return maxAns
ans = 0
ops = [0] * n # 每个数的操作次数
maxWidth = maxAns.bit_length
for bit in range(maxWidth - 1, -1, -1):
target = ans | (1
for i, x in enumerate(nums):
# j 是从高到低第一个 target 是 1 且 x 是 0 的比特位
# 计较 target &^ x 的最高位位置
diff = target & ~x
if diff == 0:
j = 0
else:
j = diff.bit_length
# x 二进制中的高于 j-1 的位不变,其余位增大到和 target 相同
mask = (1
ops[i] = (target & mask) - (x & mask)
# 无餍,取前 m 小的操作次数
ops.sort
total_sum = sum(ops[:m])
if total_sum
ans = target # 谜底的 bit 位不错填 1
return ans
if __name__ == "__main__":
nums = [3, 1, 2]
k = 8
m = 2
result = maximumAND(nums, k, m)
print(result)

C++齐备代码如下:
#include
#include
#include
#include
#include
using namespace std;
int maximumAND(vector& nums, int k, int m) {
sort(nums.begin, nums.end);
int n = nums.size;
int maxAns = nums[n - 1] + k / m;
// 最大的 m 个数都颠倒
if (nums[n - m] == nums[n - 1]) {
return maxAns;
}
int ans = 0;
vector ops(n, 0); // 每个数的操作次数
int maxWidth = 32 - __builtin_clz(maxAns); // 计较二进制位数
for (int bit = maxWidth - 1; bit >= 0; bit--) {
int target = ans | (1
for (int i = 0; i
int x = nums[i];
// 计较 target & ^x 的最高位位置
int diff = target & ~x;
int j = 0;
if (diff != 0) {
j = 32 - __builtin_clz(diff); // 计较 diff 的二进制位数
}
// j-1 是从高到低第一个 target 是 1 且 x 是 0 的比特位
// target = 10110
// x = 11010
// ^
// j-1
// x 二进制中的高于 j-1 的位不变,其余位增大到和 target 相同
// 上头的例子要把 010 酿成 110
int mask = (1
ops[i] = (target & mask) - (x & mask);
}
// 无餍,取前 m 小的操作次数
sort(ops.begin, ops.end);
int sum = 0;
for (int i = 0; i
sum += ops[i];
}
if (sum
ans = target; // 谜底的 bit 位不错填 1
}
}
return ans;
}
int main {
vector nums = {3, 1, 2};
int k = 8;
int m = 2;
int result = maximumAND(nums, k, m);
cout
return0;
}

咱们确信东谈主工智能为闲居东谈主提供了一种“增强用具”,并勤劳于共享全方向的AI常识。在这里,您不错找到最新的AI科普著作、用具评测、擢升效果的秘密以及行业瞻念察。
接待缓和“福大大架构师逐日一题”亚搏yabo(中国),发音书可取得口试贵府,让AI助力您的畴前发展。