题目:请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。例如,在下面的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.\n");
else
printf("FAILED.\n");
} //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] == '\0')
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;
}

剑指offer笔记面试题12----矩阵中的路径的更多相关文章

  1. 【剑指Offer】面试题12. 矩阵中的路径

    题目 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左.右.上.下移动一格.如果一条路径经过了矩阵的某一格,那么该路径 ...

  2. 《剑指offer》面试题12. 矩阵中的路径

    问题描述 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左.右.上.下移动一格.如果一条路径经过了矩阵的某一格,那么该 ...

  3. 剑指Offer(书):矩阵中的路径

    题目: * 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.* 路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子.* 如果一条路径经 ...

  4. 剑指offer笔记面试题3----数组中重复的数字

    题目一:找出数组中重复的数字.在一个长度为n的数组里的所有数字都在0~n-1的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次.请找出数组中任意一个重复的数字.例如 ...

  5. 《剑指offer》面试题12:打印1到最大的n位数

    面试题12:打印1到最大的n位数 剑指offer题目12,题目如下 输入数字n,按顺序打印出1到最大的n位十进制数,比如输入3,则打印出1,2,3一直到最大的三位数999 方法一 和面试题11< ...

  6. 【剑指offer】面试题 15. 二进制中 1 的个数

    面试题 15. 二进制中 1 的个数 题目描述 题目:输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. Java 实现 方法一 public class Solution { // y ...

  7. 【剑指offer】面试题 22. 链表中倒数第 K 个节点

    面试题 22. 链表中倒数第 K 个节点

  8. 剑指offer笔记面试题4----二维数组中的查找

    题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 测试用例: 二维数组中包含 ...

  9. 剑指offer笔记面试题10----斐波那契数列

    题目:求斐波那契数列的第n项.写一个函数,输入n,求斐波那契数列的第n项.斐波那契数列的定义如下:f(0) = 0, f(1) = 1,f(n) = f(n - 1) + f(n - 2). 测试用例 ...

随机推荐

  1. appium+java(八)获取Toast内容信息

    前言 Appium中很经典的问题了,在两年前也就是2017年3月6号07:22分,我才看到appium1.6.3版本的发布,更新内容为Ios上可以实现Toast的获取,而Windows也就是安卓端,还 ...

  2. python:json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes问题解决

    有如下一个文件,内容如下 { "test1": "/root/test/test1.template", "test2": "/r ...

  3. 批量SSH key-gen无密码登陆认证脚本

    SSH key-gen无密码登录认证脚本 使用为了让linux之间使用ssh不需要密码,可以采用了数字签名RSA或者DSA来完成.主要使用ssh-key-gen实现. 通过 ssh-key-gen 来 ...

  4. 完整开发流程管理提升与系统需求分析过程 随堂笔记(day 1) 【2019/10/14】

    Top12原则: 主要资源,重要功能,依据需求重要度进行资源分配, 项目100功能 1 day -> 100Task -> 10 Dev 20% 80% 开发各阶段流程及规范   需求.架 ...

  5. 用js写一个鼠标坐标实例

    HTML代码 写一个div来作为鼠标区域 div中写一个span显示坐标信息 <body> <div id=""> <span></spa ...

  6. docker快速安装rabbitmq

    1.进入docker hub镜像仓库地址:https://hub.docker.com/ 2.搜索rabbitMq,进入官方的镜像,可以看到以下几种类型的镜像:我们选择带有“mangement”的版本 ...

  7. Cocos Creator 资源加载流程剖析【六】——场景切换流程

    这里讨论场景切换的完整流程,从我们调用了loadScene开始切换场景,到场景切换完成背后发生的事情.整个流程可以分为场景加载和场景切换两部分,另外还简单讨论了场景的预加载. 加载场景的流程 load ...

  8. 原生js的2048的制作过程

    1.首先我们来看一下效果图 开始: 结束: 接下来我们来实现代码部分: HTML部分: 2048大家应该都玩过,首先我们要准备16个盒子让它4*4排列,这里的css我就不说了,这应该使我们都会的,在这 ...

  9. netcore 2.2 封装 AutoMapper

    在上篇中我们通过创建一个类并继承autoMapper的Profile类 public class Mappings : Profile { public Mappings() { CreateMap& ...

  10. Delphi 调用C# 编写的DLL方法

    近来,因工作需要,必须解决Delphi写的主程序调用C#写的dll的问题.在网上一番搜索,又经过种种试验,最终证明有以下两种方法可行:    编写C#dll的方法都一样,首先在vs2005中创建一个“ ...