1.斐波那契数列(剑指offer第10题)
解法1:递归(缺点:重复计算太多)
def Fibonacci(n):
if n==0:
return 0
if n==1:
return 1
if n==2:
return 1
return Fibonacci(n-1)+Fibonacci(n-2)
解法2:迭代,保存计算过的值
a=0
b=1
for i in range(2,n+1):
c=a+b
a=b
b=c
print(c)
相关题目:跳台阶
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
思路:1.假设第一次跳的是一阶,那么剩下的是n-1个台阶,跳法是f(n-1);2.假定第一次跳的是2阶,那么剩下的是n-2个台阶,跳法是f(n-2)。由1,2得总跳法为: f(n) = f(n-1) + f(n-2)。只有一阶的时候 f(1) = 1 ,只有两阶的时候可以有 f(2) = 2。转化为斐波那契数列。
贴瓷砖
用2*1的小矩形横着或竖着去覆盖更大的矩形。总共有多少种方法?
兔子繁殖
有一对兔子,从出生后第5个月起每个月都生一对兔子,小兔子长到第五个月后每个月又生一对兔子,假如兔子都不死,问第n个月兔子对数为多少?
1 1 1 1 2 3 4 5 7 10
f(n)=f(n-1)+f(n-4)
回溯法:回溯法非常适合由多个步骤组成的问题,并且每个步骤都有多个选项。当在某一步选择了其中一个选项时,就会进入下一步,然后面临新的选项。
2.矩阵中的路径(剑指offer12题)
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 例如 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
思路:以矩阵每个位置为起点遍历寻找路径: 副函数:首先判断数组是否越界以及该位置是否被访问过,如果满足任何一项返回False; 如果该位置值等于字符串值且字符串已经走到最后一位:返回true;
如果该位置值等于字符串值:继续寻找其他的四个方向,只要有一个方向为True即为成功。
def hasPath(matrix, rows, cols, path):
pathlength=0
for row in range(rows):
for col in range(cols):
visited = [[0 for i in range(cols)] for j in range(rows)]
if(hasPathCore(matrix,rows,cols,row,col,path,pathlength,visited)):
return True
del visited
return False
def hasPathCore(matrix,rows,cols,row,col,path,pathlength,visited):
if row>=rows or col>=cols or row<0 or col<0 or visited[row][col]==1:
return False
if matrix[row][col]==path[pathlength] and pathlength == len(path)-1:
return True
has = False
if (matrix[row][col]==path[pathlength]):
pathlength+=1
visited[row][col]=1
A=hasPathCore(matrix, rows, cols, row+1, col, path, pathlength, visited)
B=hasPathCore(matrix, rows, cols, row, col+1,path, pathlength, visited)
C=hasPathCore(matrix,rows,cols,row-1,col,path,pathlength,visited)
D=hasPathCore(matrix,rows,cols,row,col-1,path,pathlength,visited)
has=A or B or C or D
if not has:
pathlength-=1
visited[row][col]=0
return has
3.机器人的运动范围(剑指offer13题)
地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格 [35, 38],因为3+5+3+8=19。请问该机器人能够到达多少个格子?
思路:建立一个标记数组,标记位置是否被访问过;然后从0,0位置开始遍历:如果当前位置未被访问过,则sum+1,并从4个方向继续搜寻可以移动的位置; 否则返回0。
#判断一个数的数位之和的函数
def func(n):
if n<=9:
return n
sum=0
while n>9:
term = n % 10
n = n//10
sum+=term
sum+=n
return sum
#寻找路径函数
def findcount(m,n, i, j, k, visited):
if visited[i][j]==0:
visited[i][j]=1
min1, min2, min3, min4 = 0,0,0,0
if func(i+1)+func(j)<=k and i+1<m:
min1 = findcount(m,n ,i+1,j,k,visited)
if func(i)+func(j+1)<=k and j+1<n:
min2 = findcount(m,n,i,j+1,k,visited)
if func(i-1)+func(j)<=k and i-1>=0:
min3 = findcount(m,n ,i-1,j,k,visited)
if func(i)+func(j-1)<=k and j-1>=0:
min4 = findcount(m,n,i,j-1,k,visited)
return min1+min2+min3+min4+1
else:
return 0
visited = [[0 for i in range(n)] for j in range(m)]
sum = findcount(m,n, 0, 0, k, visited)
print(sum)