常见算法之回溯法

一、基本思想

回溯法(Backtracking)是一种通过尝试所有可能的解决方案来求解问题的方法。它通常适用于在给定约束条件下搜索问题的所有解,或者找到满足特定条件的一个解。

二、适用场景

回溯法适用于以下情况:

  • 组合问题:需要找出满足特定条件的组合。
  • 排列问题:需要找出满足特定条件的排列。
  • 图问题:需要找出满足特定条件的路径或遍历。
  • 棋盘问题:需要找出满足特定条件的棋盘布局或解决方案。

三、求解步骤

回溯法的求解步骤如下:

1. 选择路径:在每一步选择中,根据问题的限制条件和约束条件,选择一个合适的路径。
2. 探索路径:根据选择的路径,继续向下探索,进入下一步。
3. 撤销选择:当发现当前路径不满足条件时,需要回退到上一步,撤销选择,选择其他路径。
4. 终止条件:当达到终止条件时,找到一个解,或者已经搜索完所有可能的路径。

注📢:回溯算法的常用手段是DFS深度优先算法+剪枝,而DFS算法一般用递归或栈方法实现。

四、算法案例

题目:剑指Offer 12 矩阵中的路径

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
例如,在下面的 3×4 的矩阵中包含单词 “ABCCED”(单词中的字母已标出)。
在这里插入图片描述
输入:board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “ABCCED”
输出:true

利用回溯法求解:

func exist(board [][]byte, word string) bool {
	// 避免取值出错
	if len(board) == 0 || len(board[0]) == 0 {
		return false
	}
	var dfs func(i, j, k int) bool
	dfs = func(i, j, k int) bool {
		if i < 0 || i >= len(board) || j < 0 || j >= len(board[0]) || board[i][j] != word[k] {
			return false
		}
		if k == len(word)-1 {
			return true
		}
		// 先临时修改该位置的值,避免搜索下一个值时造成影响
		board[i][j] = ' '
		// 按照下、右、左、上顺序搜索下一值
		ans := dfs(i+1, j, k+1) || dfs(i, j+1, k+1) || dfs(i, j-1, k+1) || dfs(i-1, j, k+1)
		// 值复原
		board[i][j] = word[k]
		return ans
	}
	for i, arr := range board {
		for j, _ := range arr {
			fmt.Println("i:", i, ", j:", j)
			if dfs(i, j, 0) {
				return true
			}
		}
	}
	return false
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值