矩阵中的路径(剑指offer-12)

1、题目介绍

    设计一个函数,用来判断在一个矩阵中是否存在一条包含某个字符串所有字符的路径,路径可以从矩阵中任意一格开始,每一步可以在矩阵中向左、右、上、下各移动一格,如果一条路径经过了矩阵中的某一格,那么该路径不能再次进入该格子。 例下 3 x 4的矩阵中包含一条字符串"bfce"的路径,但是矩阵中不包含"abfb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。

                                                      

2、解题思路

    回溯法:首先在矩阵任选一个格子作为路径的起点。假设矩阵中某个格子的字符为char, 并且这个格子将对应于路径上第 i 个字符。如果路径上第 i 个字符不是char,那个这个格子不可能处在路径上的第 i 个位置。如果路径上的第 i 个字符正好是char,那么到相邻的格子寻找路径上的第 i + 1 个字符。除矩阵边界上的格子之外,其它格子都有4个相邻的格子。重复这个过程,知道路径上的所有字符都在矩阵中找到相应的位置。由于路径不能重重复进入矩阵的格子,所以还需要定义和字符矩阵大小一样的布尔矩阵,用来标识路径是否已经进入了每个格子。代码如下:

// 矩阵中以某个格子为起点的路劲是否包含给定的字符串
bool HasPathCore(vector<vector<char>>& matrix, 
                 int rows, 
                 int cols, 
                 int row, 
                 int col,
                 string str,
                 int& pathlen,
                 bool* visited)
{
    if (str[pathlen] == '\0')
    {
        return true;
    }
    bool haspath = false;
    if (row >= 0 
        && row < rows 
        && col >=0 
        && col < cols 
        && matrix[row][col] == str[pathlen]
        && !visited[row * cols + col])
    {
        ++pathlen;
        visited[row * cols + col] = true;    

        haspath = HasPathCore(matrix, rows, cols, row, col - 1, str, pathlen, visited)
            || HasPathCore(matrix, rows, cols, row - 1, col, str, pathlen, visited)
            || HasPathCore(matrix, rows, cols, row, col + 1, str, pathlen, visited)
            || HasPathCore(matrix, rows, cols, row + 1, col, str, pathlen, visited);

        if (!haspath)
        {
            --pathlen;
            visited[row * cols + cols] = false;
        }
    }
    return haspath;
}


// 矩阵中的路径
bool PathInMatrix(vector<vector<char>>& matrix, int rows, int cols, string str)
{
    int num = rows * cols;
    bool *visited = new bool[num];
    int pathlen = 0;
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            if (HasPathCore(matrix, rows, cols, i, j, str, pathlen, visited))
            {
                return true;
            }
        }        
    }
    delete [] visited;
    return false;    
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值