🗒️3315. 构造最小位运算数组 II
2025-2-26
| 2025-2-26
0  |  阅读时长 0 分钟
type
status
date
slug
summary
tags
category
icon
password
创建时间
Feb 26, 2025 02:34 AM
给你一个长度为 n 的质数数组 nums 。你的任务是返回一个长度为 n 的数组 ans ,对于每个下标 i ,以下 条件 均成立:
  • ans[i] OR (ans[i] + 1) == nums[i]
除此以外,你需要 最小化 结果数组里每一个 ans[i] 。
如果没法找到符合 条件 的 ans[i] ,那么 ans[i] = -1 。
质数 指的是一个大于 1 的自然数,且它只有 1 和自己两个因数。

位运算

x|(x+1) 的本质是把二进制最右边的 0 置为 1,并且题目要求答案最小。因此,我们的目的就变为了做相反的操作,将 x 的二进制位,最低位的第一次出现 0 位置的,右边一位的 1,变为 0。
我们如何找出现的最低位的第一个 0 的位置呢?因为第一个 0 的右边肯定都是 1,或者什么都没有(右边第一位就是 0)。
  • 右边第一位就是 0:意味着这个数是偶数,我们没办法操作啊,右边没有 1 了,返回 -1;(本题直接为 x == 2)
  • 右边第一位不是0:意味着这个 0 的右边全是 1,也就是 +1 必定会进位,并且最终进位的 1 也就是我们要找的 0。例如:100111,100111+1=101000。
我们令 t = x + 1,则最低位的 1 就是 (t & -t),然后右 1 移位,与原始的 x 异或,就可以将 1 变为 0.
或者将 x 取反,也就是将最右边的 0 变为了最右边的 1,利用 lowbit 的快速求法,即可找到该位置。同下面的写法 1.
总结:这道题的思路就是先看出题目给的位运算的本质,做转换。接着,将求最右边的 0,再次转换为求最右边的 1,最后得到答案。

写法 1

把 101111 取反,得 010000,其 lowbit=10000,右移一位得 1000。把 101111 与 1000 异或,即可得到 100111。

写法 2

把 101111 加一,得 110000,再 AND 101111 取反后的值 010000,可以得到方法一中的 lowbit=10000。

📎 参考

  • 【题单】位运算
  • Important
  • 31. 下一个排列2571. 将整数减少到零需要的最少操作数
    Loading...