[LeetCode 周赛183] 2. 将二进制表示减到 1 的步骤数(模拟、逆序处理、巧妙解法)

1. 题目来源

链接:5377. 将二进制表示减到 1 的步骤数

2. 题目说明

在这里插入图片描述

3. 题目解析

方法一:模拟+逆序处理+巧妙解法

当然,转换数字的暴力方法,在 C++ 是行不通的,但支持大数运算的 pyjava,就可了。这道题也是通过人数极多。既然暴力不成,那就只能模拟,简单说下思路:

  • 首先输入是一串二进制数字串,那么对于二进制字符串来讲,除 2 就相当于左移运算,加一的话就是正常加一并考虑进位即可。分别实现这两个方法即可
  • 左移不太好考虑,我们可以换一种思想,从后向前考虑,将除 2 操作变成 index 指针的右移操作,避免了对字符串的过多操作
  • 逆序遍历输入字符串,即从二进制低位向高位进行考虑,在此不考虑首位,会利于边界条件的判断
  • 若当前位为字符 0,那么说明当前为偶数情况,就直接考虑逆序的下一位,及模拟左移操作,操作步数加 1
  • 若当前位为字符 1,那么说明当前位奇数情况,需要进行加一的操作,就需要进行一个循环判断进位的方法
    • 若当前位的前一位是字符 0,那么说明加 1 后不会再产生进位,只需要将前一位的字符 0 改为字符 1 即可
    • 若当前位的前一位是字符 1,那么说明加 1 后仍会对前一位产生进位,则采用上述判断方法循环判断前一位即可,直至前一位为字符 0,修改后 break 跳出循环
  • 在此,操作步数应该加 2 因为涉及到奇数加一的一步操作,并且也进行了一次移位操作。所以操作步数加 2
  • 最后判断若输入字符串首位为字符 0,那么说明是由进位产生的,且当前为偶数 2,那么就再将操作步数加 1 即可得到答案

上面步骤详细,建议先直接看代码,不懂处进行对照,一看就能懂了啊。

参见代码如下:

// 执行用时 :4 ms, 在所有 C++ 提交中击败了100.00%的用户
// 内存消耗 :6.5 MB, 在所有 C++ 提交中击败了100.00%的用户

class Solution {
public:
    int numSteps(string s) {
        int len = s.size(), step = 0;
        for (int i = len - 1; i > 0; --i) {
            if (s[i] == '0') ++step;
            else {
                for (int j = i - 1; j >= 0; --j) {
                    if (s[j] == '1') s[j] = '0';
                    else {
                        s[j] = '1';
                        break;
                    }
                }
                step += 2;
            }
        }
        if (s[0] == '0') return step + 1;
        
        return step;
    }
};
发布了406 篇原创文章 · 获赞 368 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/yl_puyu/article/details/105336575