【LeetCode】1404. 將二進制表示減到 1 的步驟數 Number of Steps to Reduce a Number in Binary Representation to One


題目地址: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. 1 <= s.length <= 500
  2. s 由字符 '0''1' 組成。
  3. 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 日 —— 好久不打周賽了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章