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