A.每日一题——2154. 将找到的值乘以 2
题目链接:2154. 将找到的值乘以 2(简单)
算法原理:
解法一:排序+枚举
6ms击败31.18%
时间复杂度:O(nlogn)
排序之后就有了递增的单调性,original变成2倍之后只能增加(题目说了original>=1),枚举nums每个元素的时候不需要往回看
解法二:哈希表
4ms击败61.29%
时间复杂度O(N)
直接模拟,将所有元素全扔Set里,反正也不需要用到重复的数据嘛,只要有original就把original变2倍
解法三:位运算
1ms击败92.83%
时间复杂度O(N)
①问题本质转化
最小(第一个)的非负整数 k,使得 original × 2ᵏ 不在数组里,最终答案就是 original × 2ᵏ
②只关心一类数
数组里只有形如 original × 2ᵗ(t 为自然数)的数有用,其余数直接忽略
③用一个整数标记是否存在
用 mask 的二进制位记录:
第 t 位 = 1 → original × 2ᵗ 在数组里存在
第 t 位 = 0 → 不存在
④快速筛选有效数
对每个数 x:
先判断:x 能被 original 整除
再判断:x/original 是 2 的幂(k & (k-1) == 0)
满足就把对应位标记为 1
⑤按位取反找缺失位
~mask 后:
原本存在的位(1)→ 变 0
原本缺失的位(0)→ 变 1
⑥lowbit 找“第一个缺失”
mask & -mask 能取出最右边的 1,对应最小的缺失 2ᵏ,乘回 original 就是答案
Java代码:
class Solution {
//解法一:排序+枚举
public int findFinalValue(int[] nums, int original) {
Arrays.sort(nums);
for(int x:nums)
if(x==original)
original*=2;
return original;
}
}
class Solution {
//解法二:哈希表
public int findFinalValue(int[] nums, int original) {
Set<Integer> hash=new HashSet<>();
for(int x:nums) hash.add(x);
while(hash.contains(original)) original*=2;
return original;
}
}
class Solution {
//解法三:位运算
public int findFinalValue(int[] nums, int original) {
//mask第k位为1,表示original×2ᵏ在数组中存在
int mask=0;
for(int x:nums){
//我们只关心x=original×2ᵏ这种形式的数
int k=x/original;
//满足以下两个条件
//①x是original的整数倍→能被整除
//②k是2的幂
//k&(k-1):判断是不是2的幂的经典方法
if(x%original==0&&(k&(k-1))==0)
//把mask里第k位设为1,表示original×2ᵏ存在
mask|=k;
}
//我们要找第一个不满足的:需要按位取反,取出最右侧的1,即为第一个不满足的
mask=~mask;
return original*(mask&-mask);
}
}
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)