算法基础:给定一个数字,从1开始,每次只能加一或者翻倍,求最短步数

  • Post author:
  • Post category:其他


问题描述如下,给定任意一个正整数,只允许两种操作,+1或者x2,问从1到这个数字最短需要多少步。

在这里插入图片描述

比如给定10,最短步数就是4步,如上图所示,

这个题其实和leetcode爬楼梯是一个道理,也是有递归和非递归写法的



递归求解:

首先看一下递归公式,达到某个数字n的步数,等于一步之远的数字的步数+1,这个一步之远可以是加一操作的,也可以是翻倍操作的,即



T

(

n

1

)

T(n-1)






T


(


n













1


)





或者



T

(

n

/

2

)

T(n/2)






T


(


n


/


2


)





所以状态公式就出来:





T

(

n

)

=

1

+

m

i

n

(

T

(

n

1

)

,

T

(

n

/

2

)

)

T(n) = 1+min(T(n-1), T(n/2))






T


(


n


)




=








1




+








m


i


n


(


T


(


n













1


)


,




T


(


n


/


2


)


)







代码如下:

def c(n):
	if n==1:
		return 0
	elif n%2!==0:
		return 1 + c(n-1)
	else:
		return 1 + min(c(n-1), c(int(n/2)))

这里特殊情况是如果n是奇数的时候,他就只有+1这种操作能够达到。

递归肯定是会有重复计算的,所以非递归解法通过动态规划的方式,避免了重复计算。



非递归求解

初始状态,当n=1时,step=0,n=2时,step=1, n=3时,step=2.

def dp(n):
	if n<=3:
		return n-1
	else:
		T=[0 for i in range(n+1)]
		T[1],T[2],T[3]=0,1,2
		for i in range(4, len(T)):
			if i%2!=0:
				T[i] = 1 + T[i-1]
			else:
				T[i] = 1 + min(T[i-1], T[int(i/2)])
		return T[n]



版权声明:本文为OldDriver1995原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。