编程笔试题※python实现※递归/回溯类

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的小矩形横着或竖着去覆盖更大的矩形。总共有多少种方法?

回溯法:回溯法非常适合由多个步骤组成的问题,并且每个步骤都有多个选项。当在某一步选择了其中一个选项时,就会进入下一步,然后面临新的选项。

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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章