【回溯算法应用】剑指offer题型归纳

回溯算法基本思想**

回溯法从开始结点(根结点)出发,以深度优先的方式搜索整个解空间。这个开始结点就成为一个活结点,同时也成为当前的扩展结点。
在当前的扩展结点处,搜索向纵深方向移至一个新结点。这个新结点就成为一个新的活结点,并成为当前扩展结点。
如果在当前的扩展结点处不能再向纵深方向移动(处于边界),则当前扩展结点就成为死结点.此时,应往回移动(回溯)至最近的一个活结点处,并使这个活结点成为当前的扩展结点。
回溯法即以这种工作方式递归地在解空间中搜索,直至找到所要求的解或解空间中已没有活结点时为止。
运用回溯法解题通常包含以下三个步骤:
(1)针对所给问题,定义问题的解空间;
(2)确定易于搜索的解空间结构;
(3)以深度优先的方式搜索解空间,并且在搜索过程中用剪枝函数避免无效搜索。

一、 矩阵中的路径

请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 例如
在这里插入图片描述
矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。

思路

1.判断格子的下标是否越界
2.判断是否已经进入过或是否等于字符串中的某一字符
3.判断字符串是否已匹配到最后一个字符
4.符合条件,对该格子进行标记,再对该格子的四个方向进行与字符串的下一位进行匹配
5.若四个方向都不能匹配,则回溯,把该格子的标记去除。

二、二叉树中和为某一值的路径

输入一颗二叉树的根节点和一个整数,按字典序打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路

思路

1.将结点保存在数组中
2.判断是否为叶子结点且路径之和等于输入值
是则保存该路径
3.如果左子树存在,则递归左子树
4.如果右子树存在,则递归右子树
5.不满足上述条件,则回溯,将保存结点的数组中的最后一个删除

代码


class Solution {
public:
  
    void dfs(TreeNode* root,vector<int> &ret,vector<vector<int>> &a,int sum)
    {
        ret.push_back(root->val);
        if(sum==root->val&&!root->right&&!root->left)
        {
            a.push_back(ret);
        }
        if(root->left) dfs(root->left,ret,a,sum-root->val);
        if(root->right)dfs(root->right,ret,a,sum-root->val);
        ret.pop_back();
    }
    vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {
       vector<vector<int>> a;
       vector<int>  ret;
        if(!root) return a;
        dfs(root,ret,a,expectNumber);
        return a;
    }
};`

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值