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一样,是用时最少的