一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情
一、题目描述
- 给定一个正整数
n,找到并返回n的二进制表示中两个 相邻 1 之间的 最长距离 。如果不存在两个相邻的 1,返回0。 - 如果只有 0 将两个 1 分隔开(可能不存在 0 ),则认为这两个 1 彼此 相邻 。两个 1 之间的距离是它们的二进制表示中位置的绝对差。例如,"1001" 中的两个 1 的距离为 3 。
- 示例 1:
- 输入: n = 22
- 输出: 2
- 解释
- 22 的二进制是 "10110" 。
- 在 22 的二进制表示中,有三个 1,组成两对相邻的 1 。
- 第一对相邻的 1 中,两个 1 之间的距离为 2 。
- 第二对相邻的 1 中,两个 1 之间的距离为 1 。
- 答案取两个距离之中最大的,也就是 2 。
- 示例 2:
- 输入: n = 8
- 输出: 0
- 解释
- 8 的二进制是 "1000" 。
- 在 8 的二进制表示中没有相邻的两个 1,所以返回 0 。
- 示例 3:
- 输入: n = 5
- 输出: 5
- 解释:5 的二进制是 "101" 。
- 提示:
1 <= n <= Math.pow(10, 9)
二、思路分析:
- 想要得到二进制的最长间距,首先你需要先把给到的十进制的数字转化成二进制表示,对吧
- 转化方法:
toString,传入一个数字参数,该方法会将调用这个方法的数字转化成你传入参数的进制表示。- 注意下,这个方法返回的是表示该进制数的字符串
- 例如:
n = 22,n.toString(2)返回"10110"
- 转化方法:
- 将十进制的数字转化成二进制字符串之后呢?
- 定义一个保存最长间距的变量,后面会用到
- 遍历二进制字符串,如果当前的这个字符串中的字符等于
1,再次遍历这个字符串,不过要从这个当前位置的下一个位置开始遍历,直到找到下一个等于1的字符 - 将这两个等于字符
1的位置相减取绝对值,利用Math.max方法,将之前定义保存最长间距的变量和这个差值的绝对值两两比较,返回最大的再赋值给这个结果变量
- 遍历结束后,结果变量保存的是二进制最长间距的值,返回即可
三、AC 代码:
function binaryGap(n: number): number {
let fixed = n.toString(2);
let lengths = 0;
for(let i = 0; i < fixed.length; i++){
if(fixed[i] === '1'){
for(let j = i + 1; j < fixed.length; j++){
if(fixed[i] === fixed[j]){
lengths = Math.max(lengths, Math.abs(i - j));
break;
}
}
}
}
return lengths;
};
四、总结:
- 为什么要在二次遍历前判断
fixed[i]是不是等于字符串1- 首先题目要求的是
1之间的最长间距 - 如果不在这里判断,在二层遍历里面一样需要判断
- 在二次遍历前判断的优势在于,如果首次遍历的当前字符不等于
1,那么久没必要开启二次循环,直接遍历下一个字符,省略了无效的二次遍历
- 首先题目要求的是
- 注意下字符间距的两两比较,在二次遍历的时候如果找到了距离外层的第一个字符
1,那么需要退出当前的二次遍历,也就是需要手动break一下