【Leetcode】3133. 数组最后一位的最小值

题目

给你两个整数 n 和 x 。你需要构造一个长度为 n 的 正整数 数组 nums ,对于所有 0 <= i < n - 1 ,满足 nums[i + 1] 大于 nums[i] ,并且数组 nums 中所有元素的按位 AND 运算结果为 x 。返回 nums[n - 1] 可能的 最小 值。


示例1

输入:n = 3, x = 4
输出:6

解释:

数组 nums 可以是 [4,5,6] ,最后一个元素为 6 。

示例2

输入:n = 2, x = 7
输出:15

解释:

数组 nums 可以是 [7,15] ,最后一个元素为 15 。

限制

1 < = n , x < = 1 0 8 1 <= n, x <= 10^8 1<=n,x<=108

分析:

好了,位运算,漏点漏点。
先分析一下吧:
首先题目中有说要把nums数组中所有的数字AND处理
AND处理是什么?就是1&1 = 1,1&0=0,0&0 = 0,那么这也就决定了我们的最小为就是题目中所有的AND处理后的值x.
原因在于我们要保证所有数AND后为x,即其x的二进制数中1所在的位置必须为1,且需要保证nums中所有数中存在x二进制0所在的位置必须为0。因而这就决定了我们的最小数,即nums[0]为x.
已知条件的n怎么用呢,它保证数量,我刚开始想遍历,哈哈哈哈,就是把所有的0位置上的值遍历n-1个,因为我们已知最小的数,然后走最大,每次获取最低的0,再遍历,往上加。应该就和我看到的下面的这个题解1差不多。(为啥有这个想法没写出来,原因就在于自己位运算真的很差了…)
后面又看其他的优化题解,即讲0位置搞出来,然后我们将[1,n-1]填充到这些x的0的位置上。即比如,上面示例的4 = 100B,因为n=3,因为我们最小的值知道了为2,所以我们只要再填入n-1=2个值即可,而它的0提取出来为00,则其填上1(01B),2(10B),再将其分别添加到其上,那么就得到了4,5,6.

代码展示1

class Solution {
    public long minEnd(int n, int x) {
        // n = 3:nums的长度,且对于nums[i+1]>nums[i],即低位大于高位
        // 且nums中所有元素按位 AND 的结果为x
        //以n=3,x=4为例,因为x=4,则表明nums[0] AND nums[1] AND nums[2] = 100B,则100B为最小值,后者可以在其的基础上加,即101B,110B
        // 以n=2,x=7为例,因为x=7,nums[0] AND nums[1] = 111B,所以nums[0]为7,nums[1] = 1111B = 8+7 = 15
        // 由于n的二进制有log2n位,x的二进制就有log2n+log2x位
        // 找最大的,即x = 100,n - 1 = 001,所以,1 = 100 + 001 = 101, 2  = 101+1 = 110,
        
        long res = x;
        // 则给x中0的位置上布满n-1种的1
        for(int i = 0;i<n-1;i++){
            res += 1;
            res = res | x;
        }
        return res;
    }
}

代码展示2

class Solution {
    public long minEnd(int n, int x) {
        n -= 1;  // 填入n-1
        long res = x;
        for(int j = 0;n>0;j++){
            // res 向右移动j位,并判断其最后一位是否为0,如果是那么我可以在该位上填1
            if((res >> j & 1) == 0){
                // 表明我们的n对应的位为1,则表明该位置可以添加,因而添加
                if((n&1)==1){
                    res |= 1L << j;
                }
                // n = n/2
                n >>= 1;
            }
        }
        return res;
    }
}

最后

感觉位运算需要很熟悉我们二进制操作,可以比较巧妙的用,比如我们题解1,他就是用 r e s = r e s ∣ x res = res | x res=resx,在保留x的二进制1的基础上增加1这些,这也是后面需要增强的地方。

  • 17
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值