- 作者: 負雪明燭
- id: fuxuemingzhu
- 個人博客:http://fuxuemingzhu.cn/
題目地址:https://leetcode-cn.com/problems/number-of-steps-to-reduce-a-number-in-binary-representation-to-one/
題目描述
給你一個以二進制形式表示的數字 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'
題目大意
二進制表示的數字,經過多少次變化之後能變成1.
解題方法
轉成十進制模擬
第一想法是先轉成十進制數字,然後進行模擬。但是看了字符串的長度範圍是500,即這個數字估計有 2 ^ 500 那麼大。很顯然,不能用普通的數字類型進行保存。
但是,可以使用大數類型去做。比如 Python 默認就支持無限大的數字,那麼在 Python 中是可以直接轉成 十進制 進行模擬的。
在 Java 中,可以使用 BigInteger 類來做。
Python 代碼如下。
class Solution:
def numSteps(self, s: str) -> int:
step = 0
s_int = int(s, 2)
while s_int != 1:
if s_int % 2 == 0:
s_int //= 2
else:
s_int += 1
step += 1
return step
修改二進制字符串
既然是個二進制字符串,那麼可以從最後一位就知道當前的數字是偶數還是奇數。然後根據規則對這個二進制字符串進行操作就好了。類似於字符串表示的數字進行加法。
稍微有點難度的就是二進制進行加一的操作,需要一個進位 carry 表示是否有進位。carry 默認是 1,表示要對當前的二進制字符串加 1.
C++代碼如下:
class Solution {
public:
int numSteps(string s) {
int step = 0;
while (s != "1") {
int len = s.size();
if (s[len - 1] == '1') {
addOne(s);
} else {
s = s.substr(0, len - 1);
}
step ++;
}
return step;
}
void addOne(string& s) {
int N = s.size();
int carry = 1;
for (int i = N - 1; i >= 0; --i) {
if (s[i] == '1') {
if (carry == 1) {
s[i] = '0';
carry = 1;
}
} else {
if (carry == 1) {
s[i] = '1';
carry = 0;
}
}
}
if (carry == 1) {
s = "1" + s;
}
}
};
歡迎關注負雪明燭的刷題博客,leetcode刷題800多,每道都講解了詳細寫法!
日期
2020 年 4 月 5 日 —— 好久不打周賽了