leetcode 下一个数

题目链接
就是寻找一个略大的数字和一个略小的数字
首先说一下如何找略小的数字
分析略小的数字
先举例子
0100 0111 比这个略小的 0011 1100
0010 0000 比这个略小的 0001 0000

多分析几个数字,可知,就是找到 10,然后转换成01,并且后边如果有1的话,全都移到最靠近01的右边。
代码实现:

		int copy = num;//先复制一份,因为后面需要将这个数字进行移位
        //略小 找 10  变 01  并将 1111.。。移近 01
        int bitCount = 0;//记录10后面一共有多少位,因为后面在将10变为01的时候需要
        //开始寻找 10
		//将数字与 3也就是  与 11 可以求出最后两位是 00  或者 01  或者 10 或者 11
        while ((copy & 3) != 2){
        	//如果进来了,说明  copy最后两位不是 10
            if(copy == 0){//如果copy等于0了,那么再怎么移位,也不可能移出10了,为了避免死循环,此时应该break
                break;
            }
            copy >>= 1;//左移一位,说明此时还没有找到10
            bitCount++;//此时10后面至少有一位
        }
		//出循环说明,要不就是找到了10  要不就是整个数字的二进制中不存在10
        if(copy!=0){// copy不等于0说明找到了10
        	//将copy左移的总的位数 全部移动回来,但是此时10  后面全是0了,不管原来是多少,此时都是0了
        	//假设一开始是0100 0111  此时copy=010
        	//copy = 010 * 2^5  = 0100 0000
            copy = (int)(copy * Math.pow(2,bitCount));
            
            //然后我们需要将后面如果有1,则移到最靠近10的位置
            //首先,我们分析一下,后面可能的情况
            // 简单分析就可知,后面只能是 000000   或者000001111
            //就是后面要不就是全是0   要不就是好多0在好多1前面   只有这两种情况
            int yu = num - copy;

			//然后我们将10变为01 也就是  0100 0000 变为 0010 0000
			//只要copy - 2^5 即可
            copy = (int)(copy - Math.pow(2,bitCount));// 10变  01
			
			
            if(yu!=0){
            	//此时说明是好多0在好多1前面,反之,如果后面全是0,那么就不用处理了,只要10变01就结束了
            	//接下来就是我们如何确定yu移到了最靠近01的位置
            	//只需要比较  最靠近01的位置设置为1,只要yu大于等于这个数字了,说明已经到了最靠近的位置了
                while (yu < Math.pow(2,bitCount-1)){
                    yu <<= 1;
                }
                copy += yu;//此时将后面的数字加上即可
            }
        }else{//此时说明整个数字中不存在10也就是说,全是1,也就是最大的那个数字
            copy = -1;
        }

找到略大的也是同样的道理,不同的是,需要找的是01,变为10,并将右边的1,全部移动到最右边

整体代码:

class Solution {
    public int[] findClosedNumbers(int num) {
        int copy = num;
        //略小 找 10  变 01  并将 1111.。。移近 01
        int bitCount = 0;
        while ((copy & 3) != 2){
            if(copy == 0){
                break;
            }
            copy >>= 1;
            bitCount++;
        }

        if(copy!=0){
            copy = (int)(copy * Math.pow(2,bitCount));
            int yu = num - copy;// yu一定是   000000111111
            copy = (int)(copy - Math.pow(2,bitCount));// 10变  01
            if(yu!=0){
                while (yu < Math.pow(2,bitCount-1)){
                    yu <<= 1;
                }
                copy += yu;
            }
        }else{
            copy = -1;
        }

        //找略大   找01变 10 并将  111移到最右边
        int copy2 = num;
        bitCount = 0;
        while ((copy2 & 3) != 1){
            copy2 >>= 1;
            bitCount++;
            if(bitCount==30){
                break;
            }
        }
        if(bitCount == 30){
            return new int[]{-1,copy};
        }
        copy2 = (int)(copy2 * Math.pow(2,bitCount));
        int yu = num - copy2;
        copy2 = (int)(copy2 + Math.pow(2,bitCount));
        if(yu != 0){
            while (yu % 2 != 1){
                yu >>= 1;
            }
            copy2 += yu;
        }
        return new int[]{copy2,copy};
    }   
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值