《剑指offer》第十二题:矩阵中的路径

Posted zsy-blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《剑指offer》第十二题:矩阵中的路径相关的知识,希望对你有一定的参考价值。

// 面试题12:矩阵中的路径
// 题目:请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有
// 字符的路径。路径可以从矩阵中任意一格开始,每一步可以在矩阵中向左、右、
// 上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入
// 该格子。例如在下面的3×4的矩阵中包含一条字符串“bfce”的路径(路径中的字
// 母用下划线标出)。但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个
// 字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。
// A B T G
// C F C S
// J D E H

#include <cstdio>
#include <string>
#include <stack>

using namespace std;

bool hasPathCore(const char* matrix, int rows, int cols, int row, int col, const char* str, int& pathLength, bool* visited);

bool hasPath(const char* matrix, int rows, int cols, const char* str)
{
    //鲁棒性测试
    if (matrix == nullptr || str == nullptr || rows <= 0 || cols <= 0)
        return false;

    //路径记录矩阵
    bool* visited = new bool[rows * cols];
    memset(visited, 0, rows * cols);

    int pathLength = 0; //字符串索引
    for (int row = 0; row < rows; ++row) //遍历寻找起点
    {
        for (int col = 0; col < cols; ++col)
        {
            if (hasPathCore(matrix, rows, cols, row, col,
                str, pathLength, visited))
                return true;
        }
    }
    delete[] visited;
    return false;
}

bool hasPathCore(const char* matrix, int rows, int cols, int row,
    int col, const char* str, int& pathLength, bool* visited)
{
    if (str[pathLength] == ) //字符串尾部
        return true;

    bool hasPath = false;
    if (row >= 0 && row < rows && col >= 0 && col < cols
        && matrix[row * cols + col] == str[pathLength]
        && !visited[row * cols + col]) //对应字符串中pathLength位置字符且从未访问过
    {
        ++pathLength;
        visited[row * cols + col] = true;
       
        hasPath = hasPathCore(matrix, rows, cols, row, col - 1,
            str, pathLength, visited)
            || hasPathCore(matrix, rows, cols, row - 1, col,
                str, pathLength, visited)
            || hasPathCore(matrix, rows, cols, row, col + 1,
                str, pathLength, visited)
            || hasPathCore(matrix, rows, cols, row + 1, col,
                str, pathLength, visited);

        if (!hasPath) //此路不通, 大家就当无事发生
        {
            --pathLength;
            visited[row * cols + col] = false;
        }
    }
    return hasPath;
}
技术图片
// ====================测试代码====================
void Test(const char* testName, const char* matrix, int rows, int cols, const char* str, bool expected)
{
    if (testName != nullptr)
        printf("%s begins: ", testName);

    if (hasPath(matrix, rows, cols, str) == expected)
        printf("Passed.
");
    else
        printf("FAILED.
");
}

//ABTG
//CFCS
//JDEH

//BFCE
void Test1()
{
    const char* matrix = "ABTGCFCSJDEH";
    const char* str = "BFCE";

    Test("Test1", (const char*)matrix, 3, 4, str, true);
}

//ABCE
//SFCS
//ADEE

//SEE
void Test2()
{
    const char* matrix = "ABCESFCSADEE";
    const char* str = "SEE";

    Test("Test2", (const char*)matrix, 3, 4, str, true);
}

//ABTG
//CFCS
//JDEH

//ABFB
void Test3()
{
    const char* matrix = "ABTGCFCSJDEH";
    const char* str = "ABFB";

    Test("Test3", (const char*)matrix, 3, 4, str, false);
}

//ABCEHJIG
//SFCSLOPQ
//ADEEMNOE
//ADIDEJFM
//VCEIFGGS

//SLHECCEIDEJFGGFIE
void Test4()
{
    const char* matrix = "ABCEHJIGSFCSLOPQADEEMNOEADIDEJFMVCEIFGGS";
    const char* str = "SLHECCEIDEJFGGFIE";

    Test("Test4", (const char*)matrix, 5, 8, str, true);
}

//ABCEHJIG
//SFCSLOPQ
//ADEEMNOE
//ADIDEJFM
//VCEIFGGS

//SGGFIECVAASABCEHJIGQEM
void Test5()
{
    const char* matrix = "ABCEHJIGSFCSLOPQADEEMNOEADIDEJFMVCEIFGGS";
    const char* str = "SGGFIECVAASABCEHJIGQEM";

    Test("Test5", (const char*)matrix, 5, 8, str, true);
}

//ABCEHJIG
//SFCSLOPQ
//ADEEMNOE
//ADIDEJFM
//VCEIFGGS

//SGGFIECVAASABCEEJIGOEM
void Test6()
{
    const char* matrix = "ABCEHJIGSFCSLOPQADEEMNOEADIDEJFMVCEIFGGS";
    const char* str = "SGGFIECVAASABCEEJIGOEM";

    Test("Test6", (const char*)matrix, 5, 8, str, false);
}

//ABCEHJIG
//SFCSLOPQ
//ADEEMNOE
//ADIDEJFM
//VCEIFGGS

//SGGFIECVAASABCEHJIGQEMS
void Test7()
{
    const char* matrix = "ABCEHJIGSFCSLOPQADEEMNOEADIDEJFMVCEIFGGS";
    const char* str = "SGGFIECVAASABCEHJIGQEMS";

    Test("Test7", (const char*)matrix, 5, 8, str, false);
}

//AAAA
//AAAA
//AAAA

//AAAAAAAAAAAA
void Test8()
{
    const char* matrix = "AAAAAAAAAAAA";
    const char* str = "AAAAAAAAAAAA";

    Test("Test8", (const char*)matrix, 3, 4, str, true);
}

//AAAA
//AAAA
//AAAA

//AAAAAAAAAAAAA
void Test9()
{
    const char* matrix = "AAAAAAAAAAAA";
    const char* str = "AAAAAAAAAAAAA";

    Test("Test9", (const char*)matrix, 3, 4, str, false);
}

//A

//A
void Test10()
{
    const char* matrix = "A";
    const char* str = "A";

    Test("Test10", (const char*)matrix, 1, 1, str, true);
}

//A

//B
void Test11()
{
    const char* matrix = "A";
    const char* str = "B";

    Test("Test11", (const char*)matrix, 1, 1, str, false);
}

void Test12()
{
    Test("Test12", nullptr, 0, 0, nullptr, false);
}

int main(int argc, char* argv[])
{
    Test1();
    Test2();
    Test3();
    Test4();
    Test5();
    Test6();
    Test7();
    Test8();
    Test9();
    Test10();
    Test11();
    Test12();

    return 0;
}
测试代码

分析:回溯法本质为递归思想。

技术图片
class Solution {
public:
    bool hasPath(char* matrix, int rows, int cols, char* str)
    {
        if (matrix == nullptr || str == nullptr || rows <= 0 || cols <= 0)
            return false;
        
        bool* visited = new bool[rows * cols];
        memset(visited, 0, rows * cols);
        
        int pathLength = 0;
        for (int row = 0; row < rows; ++row)
        {
            for (int col = 0; col < cols; ++col)
            {
                if (hasPathCore(matrix, rows, cols, row, col,
                               str, pathLength, visited))
                {
                    return true;
                }
            }
        }
        delete[] visited;
        return false;
        
    }
    
    bool hasPathCore(char* matrix, int rows, int cols, int row, int col, 
                     char* str, int pathLength, bool* visited)
    {
        if (str[pathLength] == )
            return true;
        
        bool hasPath = false;
        if (row >= 0 && row < rows && col >= 0 && col < cols
           && str[pathLength] == matrix[row * cols + col]
           && !visited[row * cols + col])
        {
            ++pathLength;
            visited[row * cols + col] = true;
            
            hasPath = hasPathCore(matrix, rows, cols, row, col - 1,
                           str, pathLength, visited)
               || hasPathCore(matrix, rows, cols, row - 1, col,
                           str, pathLength, visited)
               || hasPathCore(matrix, rows, cols, row, col + 1,
                           str, pathLength, visited)
               || hasPathCore(matrix, rows, cols, row + 1, col,
                           str, pathLength, visited);
            
            if (!hasPath)
            {
                --pathLength;
                visited[row * cols + col] = false;
            }
        }
        return hasPath;
    }
};
牛客网提交代码

 

以上是关于《剑指offer》第十二题:矩阵中的路径的主要内容,如果未能解决你的问题,请参考以下文章

《剑指offer》第三十二题III:之字形打印二叉树

《剑指offer》第二十二题:链表中倒数第k个结点

《剑指offer》第三十二题I:不分行从上往下打印二叉树

《剑指offer》第二十二题(链表中倒数第k个结点)

乱序版 ● 剑指offer每日算法题打卡题解—— 搜索与回溯算法(题号12,13,34)

java刷题-剑指offer 12 矩阵中的路径