3133. 数组最后一个元素的最小值(24.8.22)

题目

给你两个整数 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 <= 108

解题思路

对于 AND 运算:
        1.00 & 1 = 0 / 0 & 0 = 0
        2.11 & 1 = 1
        3.   AND 运算的结果只会越来越小
由(3)可知,第一个数字我们需要保证是大于等于 x ,由于题目要求最小,因此第一个数为 x
例1: 以下数字省略前置的 0 
        4   1 0 0
        5   1 0 1
        6   1 1 0
        无论 x 和什么数进行 AND 运算, 0 处的数字依旧是 0 ;
        如果要想最后计算的结果还是 x 的话,则需要维护 1 的位;

        去除数字 1 最小的取值变为:(下方称之为自然序列)
        值    00  , 01   ,  10
        num   0   ,  1   ,  2
       对应n  n-3 , n-2 ,  n-1 
       于此对此创建一个自然序列:
           0000,0001,0010,0011,0100,0101,⋯
           我们的答案则是取第 n-1 个自然序列,并将其更新到原有的位置

代码

class Solution {
public:
    long long minEnd(int n, int x) {
        n--;//减去第一个数 x
        int i=0,j=0;
        long long ans=x;
        //逐位运算:
        // n>>j , 向前移动 j 位 ,直到最后一位:n>>j=0
        while(n>>j){
            //如果第 i 位是 0
            if((ans >> i & 1)==0){
                ans|=(long long)(n>>j&1)<<i;
                //n>>j 表示取第 n-1 个自然数序列的第 j 位的数,添加到第 i 位
                //通过 | 运算更新 ans 的值
                //去 0 值的
                j++;
            }
            //将第 n-1 个自然数序列向前进 1 位,用于下一个地方的 i 位的更新
            i++;
        }
        return ans;
    }
};
  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木兮xg

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值