文巾解题 397. 整数替换

这篇博客探讨了解决整数替换问题的四种方法:递归、加备忘录的递归、广度优先遍历(BFS)和位运算。通过比较,展示了如何使用备忘录和位运算来减少计算时间,特别是位运算方法,其效率与加备忘录的DFS相同,为最优解。博客还特别提到了3这个特判情况及其处理方式。
摘要由CSDN通过智能技术生成

1 题目描述

2 解题思路

2.1 递归

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

2.2 加备忘录的递归

将之前已经考虑过的数及其对应的结果存在一个字典里面

class Solution:
    def integerReplacement(self, n: int) -> int:
        dit={1:0}
        def dfs(nn):
            
            nonlocal dit
            print(dit)
            if(nn in dit):
                return(dit[nn])
            elif(nn%2==0):
                dit[nn]=1+dfs(nn//2)
                return(dit[nn])
            else:
                dit[nn]=2+min(dfs((nn+1)//2),dfs((nn-1)//2))
                return(dit[nn])
            
        dfs(n)
        print(dit)
        return(dit[n])

可以看到,相比于原先不带存储的dfs,加备忘录之后的方法时间会省下很多(因为不用一次一次递归遍历,之前已经计算过的都已经存在字典里面了)

2.3 广度优先遍历 bfs

对于一个数,当其为偶数的时候只有一种操作(除2);当其为奇数的时候存在两种操作,我们可以通过广度优先遍历求解最少操作次数。谁先得到1,谁就是最小次数。

class Solution:
    def integerReplacement(self, n: int) -> int:
        lst=[(n,0)]
        while(lst):
            tmp_n,tmp_count=lst.pop(0)
            if(tmp_n==1):
                return(tmp_count)
            elif(tmp_n%2==0):
                lst.append(((tmp_n//2),tmp_count+1))
            else:
                lst.append((tmp_n-1,tmp_count+1))
                lst.append((tmp_n+1,tmp_count+1))

2.4 位运算

偶数的二进制格式都是0bXXX0,那么直接左移即可。

对于奇数的话,如果是1,直接返回0;

大于1的奇数格式为0bXX01或者XX11,对于前一种格式直接-1(减一后的结果是00,加一后的结果是10,前者连续的零多,那么需要的操作步骤少),对于后一种格式直接+1(加一后的结果是00,减一后的结果是10,前者连续的零多,那么需要的操作步骤少)。

但是有一个数要特判,那就是3,因为3的二进制只有2位,0b11


class Solution:
    def integerReplacement(self, n: int) -> int:
        count=0
        while (n!=1):
            if(n&1==0):
                #如果最后一位为0,也就是说它是偶数,那么就向右移
                n=n>>1
            else:
                if(n==3):
                    #3的时候要特判
                    n=n-1
                else:
                    if(n&2==0):
                        n=n-1
                    else:
                        n=n+1
            count+=1
        return(count)

时间和带存储的dfs一样,是用时最少的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

UQI-LIUWJ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值