关于我
大家好,很荣幸发布我在51CTO博客的第一篇博文。通过这篇博文,我想向大家介绍一下自己,并分享一些我的技术专长和项目经验。本人是山西省太原理工大学的一名热爱技术的大一学生,对于编程和软件开发有着浓厚的兴趣。目前我主要学习内容以前端开发为主,前端领域已经学习了HTML,CSS,JavaScript,Vue全家桶;其他方面学习了C语言,python等技术,梦想是成为一名全栈工程师。本次曾参加中国高校计算机大赛-网络技术挑战赛并获省二等奖,参加第五届字节跳动青训营并获天码行空奖,参加互联网+创新创业比赛并获校金。
分享
初次发文,我想以LeetCode
上的一道题分享一些我的思考
1404. 将二进制表示减到 1 的步骤数
难度中等
给你一个以二进制形式表示的数字
s
。请你返回按下述规则将其减少到 1 所需要的步骤数:
- 如果当前数字为偶数,则将其除以 2 。
- 如果当前数字为奇数,则将其加上 1 。
题目保证你总是可以按上述规则将测试用例变为 1 。
首先拿到题目,我们不难想到用位运算的方法去解决这道题。
对于一个二进制数,如果最后一位是1,如1101
,那么显而易见它是一个奇数,令其+1即可。
如果最后一位是偶数,如1100
,那么显而易见它是一个偶数,对于二进制偶数而言,将其除以二等价于令其右移一位。
数学上的思路理清,我们换到字符串的领域思考一下
首先,将字符串切为数组
对于奇数加一
我们可以直接将末尾元素赋值为0,再向前遍历数组,若是1则变为0,若是遇到0则变为1,而后退出循环。如果进位后的二进制数长度大于原数组,则还需在数组首位添加一个1
代码如下:
if (s[s.length - 1] == 1) {
for (let i = 1; i < s.length + 2; i++) {
if (i == s.length + 1) {
s.splice(0, 0, 1)
break
}
if (s[s.length - i] == 1) {
s[s.length - i] = 0
}
else if (s[s.length - i] == 0) {
s[s.length - i] = 1
break;
}
}
num++
}
对于偶数右移
直接pop掉数组末尾的元素即可:
else {
s.pop();
num++
}
整体代码:
var numSteps = function (s) {
let num = 0;
s = s.split('')
s = s.map((e) => { return Number(e) })
while (s.length != 1) {
if (s[s.length - 1] == 1) {
for (let i = 1; i < s.length + 2; i++) {
if (i == s.length + 1) {
s.splice(0, 0, 1)
break
}
if (s[s.length - i] == 1) {
s[s.length - i] = 0
}
else if (s[s.length - i] == 0) {
s[s.length - i] = 1
break;
}
}
num++
}
else {
s.pop();
num++
}
}
return num
};
那么可能有同学就要问了,我将二进制字符串转换为十进制整数再运算,麻烦是麻烦了点,但是也可以实现吧?
对于长度较小的字符串,雀食阔以,但是如果字符串很长呢?
举个栗子:
LeetCode的某个测试样例为:"1111011110000011100000110001011011110010111001010111110001"
如果用JS转换为十进制数字的话为:
> parseInt("1111011110000011100000110001011011110010111001010111110001",2)
278675673186014720
如果还是看不出问题的话,来看看Python吧:
>>>int("1111011110000011100000110001011011110010111001010111110001",2)
278675673186014705
哦吼,不一样嘞
那么再来看看一样不一样吧:
在控制台中输入278675673186014720 == 278675673186014705
来看看布尔值吧!
278675673186014720 === 278675673186014705
true
显而易见,JS对大整数的处理不精确,所以说,还是老老实实位运算吧!
结语
最后,为了在编程领域延续自己的热爱,我在此立一个Flag,我要在这次暑假内,完成对Vue的深入了解与对React的初步学习
祝各位学有所成!