剑指offer---012(字符串在矩阵中的路径)

更多题目请点链接:《剑指offer》目录索引


问题描述:

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

思路:

1)找路径,需要遍历矩阵,可采用回溯递归的方法遍历矩阵,当是合法的坐标时,可遍历上下左右四个坐标
2)二维数组实现时,标记走过的路径,当走过合法路径后,进行标记,避免重复
3)一维数组实现时,注意下标的控制,同时记录走过的路径时,需将其保存到另一矩阵当中,注意是相同位置

代码:

1)二维数组实现

SDataType Arr[ROW][COL] = {
                            { 'a', 'b', 't', 'g' },
                            { 'c', 'f', 'c', 's' },
                            { 'j', 'd', 'e', 'h' },
                        };


//打印矩阵
void PrintArr()
{
    int i = 0, j = 0;
    for (i = 0; i < ROW; i++)
    {
        for (j = 0; j < COL; j++)
        {
            printf("%c ", Arr[i][j]);
        }
        printf("\n");
    }

    printf("\n\n");

}


//递归法
int HasPath(SDataType arr[ROW][COL], SDataType* str, int row, int col)
{
    assert(arr&&str);
    int haspath = 0;

    //当字符串探测完毕即为通路
    if (*str == '\0')
        return 1;

    if (row >= 0 && row < ROW && col >= 0 && col < COL)
    {
        if (arr[row][col] == *str && arr[row][col]!='0')
        {
            //如果是有效通路,置位'0',并检查下一个字符
            ++str;
            arr[row][col] = '0';

            //探测上下左右
              haspath = HasPath(arr, str, row - 1, col) ||
                        HasPath(arr, str, row + 1, col) ||
                        HasPath(arr, str,row, col - 1)  ||
                        HasPath(arr, str, row,col + 1);

              if (!haspath)
              {
                  --str;
              }
        }
    }

    return haspath;
}

//判断是否为路径
int  StringIspath(SDataType (*arr)[COL], SDataType* str)
{

    assert(arr&&str);

    int row = 0;
    int col = 0;
    for (row = 0; row < ROW; row++)
    {
        for (col = 0; col < COL; col++)
        {
            if (HasPath(arr, str, row, col))
            {
            //是通路返回1,不是返回0
                return 1;
            }
        }
    }

    return 0;

}


void Test()
{
    SDataType str[] = "bfce";
    PrintArr();
    int ret = StringIspath(Arr, str);
    printf("IsPath?%d \n\n\n", ret);

    PrintArr();


}

void  Test1()
{
    SDataType str[] = "bfcb";
    PrintArr();
    int ret = StringIspath(Arr, str);
    printf("IsPath?%d \n\n\n", ret);



}


void  Test2()
{
    SDataType str[] = "bfc";
    PrintArr();
    int ret = StringIspath(Arr, str);
    printf("IsPath?%d \n\n\n", ret);



}

2)一维数组实现

  int Path(char* arr, char* str, int row, int col, int startrow, int startcol,int len,char* path)
{
    assert(arr&&str);
    int haspath = 0;


    //当字符串探测完毕即为通路
    if (str[len] == '\0')
        return 1;

    if (row >= 0 && row < ROW && col >= 0 && col < COL)
    {
        if (arr[startrow*col + col] == *str && str[len] != path[startrow*col + col])
        {
            //如果是有效通路,保存在另一数组中,并检查下一个字符
            ++len;
            path[startrow*col + col] = '1';

            //探测上下左右
            haspath = Path(arr, str, row, col, startrow - 1, startcol, len, path) ||
                Path(arr, str, row, col, startrow + 1, startcol, len, path) ||
                Path(arr, str, row, col, startrow, startcol - 1, len, path) ||
                Path(arr, str, row, col, startrow, startcol + 1, len, path);

            if (!haspath)
            {
                --len;
                path[startrow*col + col] = '0';
            }
        }
    }

    return haspath;
}


int StringIsPath(char* arr, char* str, int row, int col,int startrow,int startcol)
{
    assert(arr&&str);
    assert(row > 0 && col > 0);
    int rows = 0, cols = 0;

    char* path = (char*)malloc(sizeof(char)*row*col);
    assert(path);
    memset(path, '0', sizeof(char)*row*col);
    for (rows = 0; rows < row; rows++)
    {
        for (cols = 0; cols < col; cols++)
        {
            if (Path(arr, str, rows, cols,startrow,startcol,0,path))
            {
            //是返回1,不是返回0
                return 1;
            }
        }
    }

    return 0;

}


void Test3()
{
     char* matrix = "ABTGCFCSJDEH";
     char* str = "BFCE";

    printf("IsPath?%d\n", StringIsPath(matrix,str,3,4,0,0));
}


void  Test4()
{
     char* matrix = "ABCESFCSADEE";
     char* str = "SEE";
     printf("IsPath?%d\n", StringIsPath(matrix, str, 3, 4, 0, 0));

}


void Test5()
{
     char* matrix = "ABCEHJIGSFCSLOPQADEEMNOEADIDEJFMVCEIFGGS";
     char* str = "SLHECCEIDEJFGGFIE";
     printf("IsPath?%d\n", StringIsPath(matrix, str, 5, 8, 0, 0));

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值