剑指offer 矩阵中的路径(C++)

本文介绍了如何在矩阵中判断是否存在一条包含给定字符串所有字符的路径。解题思路类似于'机器人的运动范围'问题,通过建立辅助矩阵记录已访问状态,并进行深度优先搜索。在遍历过程中,一旦找到匹配的字符,就进入递归,检查相邻元素是否匹配。如果所有字符都能匹配,返回true,否则继续寻找。文章最后给出了代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。
例如:
[abcesfcsadee]​\begin{bmatrix} a & b & c &e \\ s & f & c & s \\ a & d & e& e\\ \end{bmatrix}​asabfdcceese矩阵中包含一条字符串“bccedbccedbcced”的路径,但是矩阵中不包含“abcbabcbabcb”路径,因为字符串的第一个字符bbb占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。

解题思路

  • 和 机器人的运动范围 题目解题思路类似。定义一个和matrix一样大小的vector容器,初始化全部置0,每遍历一个元素,相应的vector中的位置置1。
  • 在矩阵中从头到尾遍历元素,找到和字符串第一个元素匹配的元素后,进入递归程序,依次判断和该结点相邻的结点元素是否和字符串中的下一个元素匹配,如果字符串中的每个结点在矩阵中均能有路径相匹配,则返回true,否则本次匹配失败,继续遍历矩阵,找下一个与字符串中第一个结点匹配的位置,直到遍历完成矩阵中的所有结点。
  • 每次匹配结束后,注意vector容器中所有为1的元素均要重新置零。
  • 主函数中的参数char *matrix中的matrix是指向字符串的字符串指针,字符串不存在二维情况,所以matrix[i][j]这样写是错误的,应该是matrix[i * cols + j]才是。

代码实现

class Solution {
public:
    bool IsPath(char* matrix, vector<int> &ivec, 
                int i, int j, int rows, int cols, char* str)
    {
        if(i < 0 or i >= rows or j < 0 or j >= cols)
            return false;
        if(matrix[i * cols + j] == *str and ivec[i * cols + j] == 0)
        {
            ivec[i * cols + j] = 1;
            if(*(str + 1) == '\0')
                return true;
            return IsPath(matrix, ivec, i, j + 1, rows, cols, str + 1) or 
                IsPath(matrix, ivec, i + 1, j, rows, cols, str + 1) or
                IsPath(matrix, ivec, i, j - 1, rows, cols, str + 1) or
                IsPath(matrix, ivec, i - 1, j, rows, cols, str + 1);
        }
        return false; // 注意不合题意的要返回false。
    }
    void transferToZero(vector<int> &ivec)
    {
        vector<int>::iterator iter = ivec.begin();
        while((iter = find(ivec.begin(), ivec.end(), 1)) != ivec.end())
            *iter = 0;
    }
    bool hasPath(char* matrix, int rows, int cols, char* str)
    {
        vector<int> ivec(rows * cols, 0);
        int i = 0, j = 0;
        for(; i < rows; i++)
            for(j = 0; j < cols; j++)
                if(IsPath(matrix, ivec, i, j, rows, cols, str))
                    return true;
                else
                    transferToZero(ivec);
        return false;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值