求二进制中1的最大间距

382 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第16天,点击查看活动详情

题目描述

给定一个正整数 n,找到并返回 n 的二进制表示中两个 相邻 1 之间的 最长距离 。如果不存在两个相邻的 1,返回 0

如果只有 0 将两个 1 分隔开(可能不存在 0 ),则认为这两个 1 彼此 相邻 。两个 1 之间的距离是它们的二进制表示中位置的绝对差。例如,"1001" 中的两个 1 的距离为 3

示例

输入:n = 22
输出:2
解释:22 的二进制是 "10110" 。
在 22 的二进制表示中,有三个 1,组成两对相邻的 1 。
第一对相邻的 1 中,两个 1 之间的距离为 2 。
第二对相邻的 1 中,两个 1 之间的距离为 1 。
答案取两个距离之中最大的,也就是 2 。
输入: n = 8
输出: 0
解释: 8 的二进制是 "1000" 。
在 8 的二进制表示中没有相邻的两个 1,所以返回 0 。
输入: n = 5
输出: 2
解释: 5 的二进制是 "101" 。

提示

  • 1 <= n <= 109^9

与运算

与运算关系0&0=0;0&1=0;1&0=0;1&1=1,那么根据以上的关系,我们可以利用1 & 1 = 1 这一点,我们可以移动1的位置,判断目标值n二进制中各个1出现的位置,具体步骤如下:

  1. 定义一个32的位数组(在Java中,int类型为32位)
  2. 将数字1逐位移动,与目标值n与运算
  3. 当符合条件时,保存当前位置i
  4. 计算当前位置与前一次匹配位置间的差距,更新结果
  5. 返回结果
class Solution {
    public int binaryGap(int n) {
        // 保存二进制中1出现的位置
        int[] arr = new int[32];
        int res = 0;
        for(int i = 0, j = 0; i < 32; ++i){
            // 将 1 位移,跟目标值做与运算,判断当前位置是否不等于 0
            if(((1 << i) & n) != 0){
                // 保存出现的位置
                arr[j] = i;
                if(j > 0){
                    // 更新最大值
                    res = Math.max(res, arr[j] - arr[j - 1]);
                }
                // 将指针移动到下一位
                ++j;
            }
        }

        // 返回结果
        return res;
    }
}