1. 问题描述:
给你一个以二进制形式表示的数字 s 。请你返回按下述规则将其减少到 1 所需要的步骤数:
如果当前数字为偶数,则将其除以 2 。
如果当前数字为奇数,则将其加上 1 。
题目保证你总是可以按上述规则将测试用例变为 1 。
示例 1:
输入:s = "1101"
输出:6
解释:"1101" 表示十进制数 13 。
Step 1) 13 是奇数,加 1 得到 14
Step 2) 14 是偶数,除 2 得到 7
Step 3) 7 是奇数,加 1 得到 8
Step 4) 8 是偶数,除 2 得到 4
Step 5) 4 是偶数,除 2 得到 2
Step 6) 2 是偶数,除 2 得到 1
示例 2:
输入:s = "10"
输出:1
解释:"10" 表示十进制数 2 。
Step 1) 2 是偶数,除 2 得到 1
示例 3:
输入:s = "1"
输出:0
提示:
1 <= s.length <= 500
s 由字符 '0' 或 '1' 组成。
s[0] == '1'
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/number-of-steps-to-reduce-a-number-in-binary-representation-to-one
2. 思路分析:
① 一开始看到题目的时候比较容易想到的是将字符串先转为十进制的数字,使用一个循环来模拟整个的过程,实际上这种做法是可以解决一小部分数据的,当字符串表示的数字可以使用int或者long存储的时候这个时候存储没有溢出使用这个方法是没有任何问题的,但是一旦字符串超过某个长度之后那么使用int或者long存储就溢出了,在一开始的时候没有看字符串的长度最长为所以使用了上面提到的方法来做,字符串的长度为500使用基本的数据类型存储早就溢出来了所以是得不到正确答案的
② 我们只能够采取另外一种方法来做,我们首先需要观察字符串,由二进制数字表示的特点可以知道,二进制字符串加1的操作我们完全是可以模拟出来的,我们可以先列举几个简单的二进制数字来看一下加1的操作是怎么样实现的,并且加1只对奇数进行操作
奇数(二进制最末尾数字是1):1111000111,这个数字为奇数,在加1的时候那么就需要从字符串末尾开始找第一个为0的数字,所以我们可以在循环中寻找,循环未结束之前说明这些位置上都是1,当遇到字符串的位置为0的时候说明循环结束说明这个位置应该是1,这个时候需要截取从字符串开始到循环结束这个位置的字符串 + "1" + 后面循环过程中需要拼接的0字符串,这个可以使用StringBuilder来拼接和翻转,对于这个数字来说我们需要拼接的是 "111100" + "1" + "000"(循环过程中将1变为0使用StringBuilder拼接)
假如为偶数的话根据二进制数字的特点可以知道除以2可以移除掉最末尾的二进制数字,所以在截取字符串的时候到字符串长度的前一位即可
③ 处理细节可以结合简单具体的例子来实现
3. 代码如下:
通过代码:
class Solution {
public int numSteps(String s) {
/*变成字符串的加法来做*/
/*判断奇数还是偶数需要看字符串的最后一位数字*/
int count = 0;
while (s.length() != 1){
char c = s.charAt(s.length() - 1);
/*表示偶数比较好处理直接去掉字符串的最后一位即可*/
if (c == '0') s = s.substring(0, s.length() - 1);
else s = solve(s);
++count;
}
return count;
}
private String solve(String s) {
/*字符串加1操作*/
StringBuilder last = new StringBuilder("");
int index = s.length() - 1;
while (index >= 0 && s.charAt(index) == '1'){
last.append("0");
--index;
}
last.append("1");
if (index >= 0){
return s.substring(0, index) + last.reverse().toString();
}
return last.reverse().toString();
}
}
一开始的代码:
class Solution {
public int numSteps(String s) {
int n = solve(s);
int count = 0;
while (n != 1){
if (n % 2 == 0) n /= 2;
else n += 1;
++count;
}
return count;
}
private int solve(String s) {
int radix = 1, sum = 0;
for (int i = s.length() - 1; i >= 0; --i){
char c = s.charAt(i);
if (c == '1') sum += radix;
radix *= 2;
}
return sum;
}
}