题目描述
给你一个以二进制形式表示的数字 s
。请你返回按下述规则将其减少到 1 所需要的步骤数:
-
如果当前数字为偶数,则将其除以 2 。
-
如果当前数字为奇数,则将其加上 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
输入:s = "10"
输出:1
解释:"10" 表示十进制数 2 。
Step 1) 2 是偶数,除 2 得到 1
输入:s = "1"
输出:0
限制
1 <= s.length <= 500
s
由字符'0'
或'1'
组成。s[0] == '1'
算法
(模拟) $O(n^2)$
- 将原字符串反转,按照高精度计算的方式模拟整个过程。
时间复杂度
- 如果字符串的长度为 $n$,则大约需要 $O(n)$ 步使其变为 1。每一步的时间复杂度最坏为 $O(n)$。
- 故总时间复杂度为 $O(n^2)$。
空间复杂度
- 仅需要常数的额外空间。
C++ 代码
class Solution {
public:
int numSteps(string s) {
int ans = 0;
reverse(s.begin(), s.end());
while (s.length() > 1) {
ans++;
if (s[0] == '0') {
for (int i = 0; i < s.length() - 1; i++)
s[i] = s[i + 1];
s.pop_back();
} else {
s[0]++;
int i = 0;
while (i < s.length() - 1 && s[i] == '2') {
s[i] = '0';
s[i + 1]++;
i++;
}
if (s.back() == '2') {
s.back() = '0';
s += '1';
}
}
}
return ans;
}
};