【数学】C023_二进制间距(计数法 | 下标相减法)

一、题目描述

Given a positive integer N,
find and return the longest distance between 
two consecutive 1's in the binary representation of N.
If there aren't two consecutive 1's, return 0.

例如,数字9具有二进制表示1001,包含长度为2的二进制间隙。
数字529具有二进制表示1000010001,并且包含两个二进制间隙:长度4和长度3的一个。

二、题解

(1) 计数法

每次遇到 位1,则重新开始记录并比较0的数量zeroCnt,取它的最大值。

/**
 * @param N
 * @return
 */
public int binaryGap1(int N) {
  int ans = 0;
  int zeroCnt = 0;
  while(N >= 1) {
    // 只有遇到1以后,的0才会被计数,不然如果N==8(1000),会返回3
    if((N & 1) == 0 && zeroCnt > 0) {
      zeroCnt++;
    }else if((N&1) == 1){
      ans = ans > zeroCnt ? ans : zeroCnt;
      zeroCnt=1;
    }
    N >>= 1;
  }
  return ans;
}

(2) 数组记录位 1 的索引法

record数组记录每一个位1的索引,遇到1则指向1的指针自增1。而全局指针每次加1,在最后两两比较record数组的每一个元素的差值,得出最大值。

/**
 * @param N
 * @return
 */
public int binaryGap2(int N) {
  int ans = 0;
  int i = 0;  // 指向位1的指针。
  int[] record = new int[32];
  for (int j = 0; j < 32; j++) {
    if ((N & 1) != 0)
      record[i++] = j; // 记录位1的下标。
    N >>= 1;
  }
  for (int k = 0; k < record.length-1; k++) {
    ans = Math.max(ans, record[k+1]-record[k]);
  }
  return ans;
}

(3) 不使用额外数组空间

不难想到,其实无需开辟一个数组来存储位 1 的下标,只需每次更新最后的位 1 二进制位下标,每次更新后,并且与之间的得到的临时最大间隔gap进行比较即可。

/**
 * @param N
 * @return
 */
public int binaryGap3(int N) {
  int gap = 0, last = -1;
  for (int i = 0; i < 32; i++) {
    if((N&1) == 1) {
      if(last >= 0)
        gap = Math.max(i-last, gap);
      last = i;
    }
    N >>= 1;
  }
  return gap;
}
发布了300 篇原创文章 · 获赞 48 · 访问量 8069

猜你喜欢

转载自blog.csdn.net/qq_43539599/article/details/103995847