397 整数替换(递归)

1. 问题描述:

给定一个正整数 n,你可以做如下操作:
1. 如果 n 是偶数,则用 n / 2替换 n。
2. 如果 n 是奇数,则可以用 n + 1或n - 1替换 n。
n 变为 1 所需的最小替换次数是多少?

示例 1:

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

示例 2:

输入:
7
输出:
4
解释:
7 -> 8 -> 4 -> 2 -> 1

7 -> 6 -> 3 -> 2 -> 1

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/integer-replacement

2. 思路分析:

① 一开始想到模拟整个过程,如果n为偶数那么n / 2,如果为奇数那么n - 1这样可以尽可能逼近1,但是这个做法实际上是忽略了一点就是有可能n为奇数加1之后有可能可以连续除以2的,也就数4的倍数,比如15就是这样一个例子,所以上面的做法是不正确的,然后想到题目中n为奇数的时候其实是有两种选择的,所以我们可以尝试这两种选择看最终能够使得n到达的最少步数是多少,因为需要尝试当前状态下n - 1还是n - 1最终能够使得步数最少,所以是可以递归来解决的(尝试所有的可能性最终得到最优解)

② 我们可以写有返回值的递归与没有返回值的递归方法,没有返回值的递归我们可以声明一个类变量,并且在方法中声明一个变量来记录到达当前的n需要的步数,到达递归出口的时候也就是n <= 3的时候与类变量的值进行比较,假如更小那么更新类变量,在具体的实现中我们可以判断出当前的数字是奇数还是偶数,假如是偶数那么直接除以2,如果是奇数那么依次调用n - 1与n + 1的递归方法尝试可能性

有返回值的递归方法其实也是类似的,只是在递归的时候需要返回对应的结果,为偶数的时候方法返回值为往下进行递归的结果加1,为奇数的时候方法返回值为递归n - 1与n + 1的递归结果中较小的结果加上1,

3. 代码如下:

有返回值:

class Solution:
    # 有返回值的递归
    def recursion(self, n: int):
        if n <= 3: return n - 1
        if n % 2 == 0: return self.recursion(n // 2) + 1
        else:
            return min(self.recursion(n - 1), self.recursion(n + 1)) + 1

    def integerReplacement(self, n: int) -> int:
        return self.recursion(n)

无返回值:

class Solution:
    # 类变量用来记录n变为1的最少的次数
    count = 0

    # cur变量用来记录变为当前数字需要的次数
    def recursion(self, n: int, cur: int):
        if n == 1:
            if cur < self.count:
                self.count = cur
            return
        if n <= 0: return
        if n % 2 == 0: self.recursion(n // 2, cur + 1)
        else:
            self.recursion(n - 1, cur + 1)
            self.recursion(n + 1, cur + 1)

    def integerReplacement(self, n: int) -> int:
        self.count = n
        self.recursion(n, 0)
        return self.count

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值