回溯算法思路总结

注意点

  1. 定义清楚递归函数函数的作用,及需要的参数,参数一般有(要搜索的对象,当前访问位置index,当前已有的一个中间结果,总的结果res,访问标记变量visited)
  2. 递归调用函数后,记得回退,把当前值从当前结果中弹出,把参数重新置为未访问。
  3. 递归函数的结束条件是,当前结果的长度等于要求的长度,或当前访问位置等于遍历对象的长度(其实就是越界一位,说明遍历完成),把当前结果加入总结果列表后返回。

数字对应字母的组合

s保存从digits[0–index-1]能得到的一个字符串,即树形结构的一条路径

    def find(self, index, digits, s, res):
        if index == len(digits):
            res.append(s)
            return res
        dic  = {'2':'abc','3':'def','4':'ghi','5':'jkl','6':'mno','7':'pqrs','8':'tuv','9':'wxyz'}
        c = digits[index]
        letters = dic[c]
        for i in letters: #对当前数字对应的3个字母向后递归调用
            res = self.find(index+1,digits,s+i,res)
        return res

排列

p中保存了一个有index个元素的排列,向这个排列的末尾加入第index+1个元素

    def find(self, nums, index, p, res,used):
        if index == len(nums):
            res.append(p[:])
            return res
        for i,n in enumerate(nums): #每次都对除了取过的所有元素递归调用
            if used[i] == 0:
                p.append(n)
                used[i] = 1
                res = self.find(nums,index+1,p,res,used)  
                p.pop(-1)
                used[i] = 0
        return res

组合

递归函数的作用是求解C(n,k),当前已经找到的组合存储在c中,从start开始取新的元素。

    def find(self, n, k, start, c, res):
        if len(c)==k:
            res.append(c[:])
            return res
        for i in range(start,n+1): # 对当前位之后的所有数字递归调用,避免重复
            c.append(i)
            res = self.find(n,k,i+1,c,res)
            c.pop(-1) # 回到上一步
        return res

二维数组搜索,判断是否存在指定路径

递归函数的作用从当前位置开始board[startx][starty]寻找word[index:],结束条件是index取到最后一位时,当前位置的值等于要找的字母,返回true;递归过程要先判断当前位置的值是否等于要找的index位置的值,如果是再递归调用上下左右寻找下一个元素,否则直接返回false。

    def find(self, board, word, index, startx, starty, visited):
        m = len(board)
        n = len(board[0])
        d = [[1,0],[0,1],[-1,0],[0,-1]]
        if index == len(word)-1:
            return board[startx][starty] == word[index]
        if board[startx][starty] == word[index]:
            visited[startx][starty] = 1
            for i in range(4): #对上下左右递归
                x = startx + d[i][0]
                y = starty + d[i][1]
                if self.inarea(x,y,m,n)==True and visited[x][y]==0 and self.find(board, word, index+1, x, y, visited) == True: # 边界不溢出,未访问过,下一步能找到
                    return True
            visited[startx][starty] = 0
        return False

岛判断

递归函数的作用是把和当前陆地相邻的陆地都标为false。

    def dfs(self,grid,x,y,visited):
        m = len(grid)
        n = len(grid[0])        
        d = [[0,1],[1,0],[-1,0],[0,-1]]
        visited[x][y] = 1
        for i in range(4): #也是对上下左右递归
            newx = x + d[i][0]
            newy = y + d[i][1]
            if self.inarea(newx,newy,m,n) and visited[newx][newy] == 0 and grid[newx][newy] == '1':
                self.dfs(grid,newx,newy,visited)
        return

八皇后

递归函数的作用是尝试摆放第index行的皇后的位置

    def find(self,n,index,row,res,col,diag1,diag2):
        if index == n:
            res.append(row[:])
            return res
        for i in range(n): #第i列,递归每一列
            if col[i] == 0 and diag1[i+index] == 0 and diag2[i-index+n-1] == 0: # 可以放,没冲突
                col[i] = 1
                diag1[i+index] = 1
                diag2[i-index+n-1] = 1
                row.append(i)
                res = self.find(n,index+1,row,res,col,diag1,diag2)
                row.pop(-1)
                col[i] = 0
                diag1[i+index] = 0
                diag2[i-index+n-1] = 0
        return res
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一、设计分析 迷宫问题是计算机科学中经典的问题之一,也是一个常见的算法练手题目。这个问题可以用回溯法算法来解决。回溯法算法是一种基于搜索的算法,它尝试所有可能的步骤来解决问题,并回溯到上一步,直到找到解决方案。这个算法适用于那些可能有多个解的问题,而且解的数量不是很大的情况。 二、算法描述与程序 1. 算法描述 (1) 将起点加入路径列表中。 (2) 按照顺时针的方向选择下一个可行的方向。 (3) 如果下一个方向可以到达终点,则将终点加入路径列表中,返回 true。 (4) 如果下一个方向不能到达终点,则将下一个方向的坐标加入路径列表中,继续递归调用该函数。 (5) 如果递归调用返回 false,则在路径列表中删除该坐标。 (6) 如果所有方向都无法到达终点,则返回 false。 2. 程序实现 下面是一个使用 Python 语言实现的迷宫问题的回溯法算法的程序: ```python def find_path(maze, start, end, path=[]): path = path + [start] if start == end: return path if start[0] < 0 or start[0] >= len(maze) or start[1] < 0 or start[1] >= len(maze[0]) or maze[start[0]][start[1]] == 1 or start in path: return None for move in [(0, 1), (1, 0), (0, -1), (-1, 0)]: next_point = (start[0] + move[0], start[1] + move[1]) if next_point not in path: new_path = find_path(maze, next_point, end, path) if new_path: return new_path return None ``` 三、测试分析与总结 1. 测试分析 为了测试迷宫问题的回溯法算法的程序的正确性,我们可以利用一些测试用例来检验。比如说,我们可以生成一个随机的迷宫,然后在里面随机选择一个起点和终点,然后使用算法来寻找路径。如果算法返回的路径与我们手工计算的路径一致,则说明算法正确。 2. 总结 回溯法算法是一种比较通用的算法,可以用来解决很多问题。这个算法的思路比较简单,但是要注意一些细节,比如说防止重复访问已访问的节点等等。在实际应用中,我们可以根据具体的问题来进行修改和优化,以达到更好的效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值