• 剑指offer笔记面试题12----矩阵中的路径


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

    a b t g
    c f c s
    j d e h

    测试用例:

    • 功能测试(在多行多列的矩阵中存在或者不存在路径)。
    • 边界值测试(矩阵中只有一行或者只有一列;矩阵和路径中的所有字母都是相同的)。
    • 特殊输入测试(输入nullptr指针)。

    测试代码:

    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);
    }
    

    本题考点:

    • 考查应聘者对回溯法的理解。通常在二维矩阵上找路径这类问题都可以应用回溯法解决。
    • 考查应聘者对数组的编程能力。我们一般都把矩阵看成一个二维的数组。只有对数组的特性充分了解,才有可能快速、正确地实现回溯法的代码。

    实现代码:

    #include <cstdio>
    #include <cstring>
    #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 || rows < 1 || cols < 1 || str == nullptr)
            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;
            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;
    }
    int main(int argc, char* argv[])
    {
        Test1();
        Test2();
        Test3();
        Test4();
        Test5();
        Test6();
        Test7();
        Test8();
        Test9();
        Test10();
        Test11();
        Test12();
        return 0;
    }
    
  • 相关阅读:
    VS2013中使用码云gitee建立源代码管理
    win10激活出现错误0xc004f074 解决方案
    List<string> 去重复 并且出现次数最多的排前面
    jQuery.extend(),jQuery.fn.extend() 区别
    js 获取范围内的随机数
    xslt/xpath对不存在属性的判断问题
    查询各科成绩不合格与合格人数
    微信开发之实现一键拨号及短信发送功能
    Git 常用命令
    Excel 表 导入导出
  • 原文地址:https://www.cnblogs.com/tangliang39/p/11693040.html
Copyright © 2020-2023  润新知