From 0a4a8c37384646f6d3a7ce279e128077d6332d51 Mon Sep 17 00:00:00 2001 From: gameloader Date: Wed, 29 May 2024 15:59:18 +0800 Subject: [PATCH] leetcode update --- content/posts/leetcode.md | 52 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/content/posts/leetcode.md b/content/posts/leetcode.md index 3b9fa61..ebb85d1 100644 --- a/content/posts/leetcode.md +++ b/content/posts/leetcode.md @@ -6551,3 +6551,55 @@ func abs(i byte, j byte)int{ } } ``` + +## day93 2024-05-29 + +### 1404. Number of Steps to Reduce a Number in Binary Representation to One + +Given the binary representation of an integer as a string s, return the number of steps to reduce it to 1 under the following rules: + +If the current number is even, you have to divide it by 2. + +If the current number is odd, you have to add 1 to it. + +It is guaranteed that you can always reach one for all test cases. +![0529LWtUuBN152FA](https://testingcf.jsdelivr.net/gh/game-loader/picbase@master/uPic/0529LWtUuBN152FA.png) + +### 题解 + +本题要注意寻找规律, 因为题目一定有解, 因此最后一定会变为类似于10000...这样的形式, 即开头为1, 后面全部为0, 这样在不断除以2最终才能得到1. 我们只需考虑对于后面的1, 需要几次给最后一位的1加1操作最终能得到1000...这样的形式. 也就是说, 我们整体考虑题目中给出的两种操作, 本来应该是按照条件奇数加一, 偶数除以二, 偶数除以二实际上就是右移一位, 使得0的数量减少一个, 现在相当于先执行所有的奇数加1操作(这里可以理解为每次给最后一位1加一, 使其进位), 将数字化为1000...这样的形式后, 0的个数就是需要除以二的次数. 观察可以发现, 需要执行加1操作的次数与第一个1和最后一个1之间的0的个数有关, 需要加1的次数正好与首末1之间的0的个数相差1. 这点可以理解为, 通过一系列的加1操作将首末1之间的0移到了整个字符串的最后面, 最终得到开头为连续的1的串, 再加1就能得到以1开头,其余全为0 的串. 如图说明了这个过程. 理解了这一点, 只需要扫描串, 记录首末1之间的0的个数, 最终结果即为首末1之间0的个数加1与串的长度的和. 注意处理串本身就是开头为连续1和串本身即为只有开头为1这两种情况. 只有开头为1直接返回长度减1, 存在大于1个的连续1则为串的长度加1. + +![0529hp7zXBIMG_78E8EB0BD2BE-1](https://testingcf.jsdelivr.net/gh/game-loader/picbase@master/uPic/0529hp7zXBIMG_78E8EB0BD2BE-1.jpeg) + +### 代码 + +```go +func numSteps(s string) int { + zeros := 0 + validzeros := 0 + ones := 0 + length := len(s) + for i,_ := range s{ + if s[i] == '1'{ + ones++ + zeros = validzeros + }else{ + validzeros++ + } + } + if zeros == 0{ + if ones == 1{ + return length - 1 + }else{ + return length + 1 + } + }else{ + return zeros + length + 1 + } +} + +``` + +### 总结 + +本题直接从最后一位开始向前遍历, 遇到0直接将结果加1, 遇到1设定一个标记进位的标记变量为1, 同时将结果加2, 如此重复即可. 注意在每次判断当前位是0还是1之前要将原本的当前位值加上进位的标记变量再判断.