2026/4/18 14:28:20
网站建设
项目流程
番禺人才网官方网站信息公布,广告设计与制作前景,山水装饰装修公司怎么样,如何注册域名免费题目链接#xff1a;3314. 构造最小位运算数组 I#xff08;简单#xff09;
3315. 构造最小位运算数组 II#xff08;简单#xff09; 算法原理#xff1a; 解法一#xff1a;暴力枚举 4ms击败30.43% 时间复杂度O(N∗M) 思路很简单#xff0c;先来一层for循环遍历链表…题目链接3314. 构造最小位运算数组 I简单3315. 构造最小位运算数组 II简单算法原理解法一暴力枚举4ms击败30.43%时间复杂度O(N∗M)思路很简单先来一层for循环遍历链表中的每个质数再针对每个质数再来一层for循环因为“|”运算的性质就是只要有1结果就是1所以 i | (i1)的结果一定i1所以内层for循环从0遍历到x-1逐步试探只要有符合的就加入到返回数组ret中然后立刻break防止多添如果没有找到就把1加入返回数组即可解法二位运算1ms击败100.00%时间复杂度O(N)想要降低时间复杂度就要观察题目的例子总结出规律再对症下药举个例子x100111时x | (x1)100111 | 101000101111x和x1必然是一奇一偶那么上述的式子其实就是把二进制最右边的0改成了1且这个 0右边都是1在上述例子中0的位置在从左往右数第3个数反过来在 x | (x1)101111的情况下倒推x需要把右边四个1的某个1变成0满足要求的x有100111、101011、101101、101110这些都是符合条件的挑出其中最小的是 100111也就是把101111最右边的0的右边的1置为0那么我们现在的目标就是找到nums[i]最右边的0的右边的1如何找到呢先找到最右边的0然后1就是最右边的1了如何找到最右边的0呢①第一个方向既然要找到这个0那么就是提取出它在位运算中提取常常使用按位与把1011111得到110000再把101111按位取反~得到010000这两个结果按位与恰好得到lowbit10000②第二个方向找到这个0也可以用异或^提取咱们要找的是最右侧的0首先明确找最右侧的1的式子是n-n那么我们可以通过对原数取反将最右侧的1转化为最右侧的0进而使用这个式子这个式子可参考下面这篇博客优选算法-位运算33.判断字符是否唯一把x101111按位取反~得到 t~x010000通过 t -t 得到lowbit10000JAVA代码class Solution { //解法一暴力解法 public int[] minBitwiseArray(ListInteger nums) { int[] retnew int[nums.size()]; int index0; //遍历每个质数 for(int x:nums){ //获取一下加入之前的index位置 int tmpindex; for(int i0;ix;i) if((i|(i1))x){ ret[index]i; break;//找到一个最小的立马弹出 } //如果没找到就添加1 if(indextmp) ret[index]-1; } return ret; } }class Solution { //解法二位运算 public int[] minBitwiseArray(ListInteger nums) { int[] retnew int[nums.size()]; int index0; for(int x:nums){ if(x2) ret[index]-1; else{ //写法一 //int lowbit(x1)~x; //写法二 int lowbit(~x)-(~x); ret[index]x^(lowbit1); } } return ret; } }