leetcode_397 整数替换

950 阅读2分钟

要求

给定一个正整数 n ,你可以做如下操作:

如果 n 是偶数,则用 n / 2替换 n 。
如果 n 是奇数,则可以用 n + 1或n - 1替换 n 。
n 变为 1 所需的最小替换次数是多少?

示例 1:

输入:n = 8
输出:3
解释:8 -> 4 -> 2 -> 1

示例 2:

输入:n = 7
输出:4
解释:7 -> 8 -> 4 -> 2 -> 17 -> 6 -> 3 -> 2 -> 1

示例 3:

输入:n = 4
输出:2

核心代码

class Solution:
    def integerReplacement(self, n: int) -> int:
        bin_n = bin(n)[2:]
        count = 0
        while bin_n != "1":
            if bin_n[-1] == "0":
                bin_n = bin_n[:-1]
            else:
                if bin_n[-2] == "1" and bin_n != "11":
                    bin_n = bin(int(bin_n,2) + 1)[2:]
                else:
                    bin_n = bin(int(bin_n,2) - 1)[2:]
            count += 1
        return count

另一解法

class Solution:
    def integerReplacement(self, n: int) -> int:
        cnt = 0
        while n != 1:
            if n == 3:
                return cnt + 2
            elif n % 2 == 0:
                n //= 2
            elif (n + 1) % 4:
                n -= 1
            else:
                n += 1
            cnt += 1
        return cnt

第三种解法

class Solution:
    def integerReplacement(self, n: int) -> int:
        if n == 1:
            return 0
        if n % 2 == 0:
            return self.integerReplacement(n // 2) + 1
        else:
            return min(self.integerReplacement(n + 1),self.integerReplacement(n - 1)) + 1

image.png

解题思路:第一种解法:遇到奇数的时候,可以选择 +1 或者 -1 ,为了最快到达1,也就是获得2的倍数还是4的倍数的问题,我们希望尽可能除以2的次数多一些,因此我们选择构造4的倍数,也就是要查看二进制最后两位数字,但是需要注意3这个特殊情况。这里直接给出思路:用二进制来处理这个整数。如果整数是偶数,直接将这个偶数除以2;如果整数是大于3的奇数,并且除以4后余3(也就是倒数第二位也是1),那么将这个奇数+1;如果整数是奇数,并且除以4以后余1(也就是倒数第二位是0),那么这个奇数-1。依据上面的规则,循环遍历,直到整数变为3为止。

对上面的思路进行解读:我们看到进入循环后,二进制最后一位是0,表示是偶数,取除了最后的0前面的所有数字,就是对数字进行除2的操作,然后我们分析最后一位不是0,那即是1,倒数第二位是1,并且该数字不是3,那么我们就是4的倍数并且对4取余是3,我们对数字进行+1操作,否则就是-1的操作,然后对操作次数进行记录即可,比较新颖的亮点就是使用二进制,做减半(除2)操作和对4取余3或1的处理,比较好。 第二种解法:就是第一种方法的10进制的做法:判断是不是整除4,是因为我们可以连续两次的除2操作,简化步骤。
第三种解法:使用递归的方式,此方式效率较低,但是思路比较好想。