• 第12题:矩阵中的路径


     题目描述

    请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则之后不能再次进入这个格子。 例如 a b c e s f c s a d e e 这样的3 X 4 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。

    考点:回溯法

    回溯法一般与递归深度优先遍历联合使用,他的核心就是不断尝试路线,倘若碰壁(走不通)则返回到上一步进行从新试探,其程序结构分为两部分: 
    (1)寻找起点,并在起点位置调用探索函数。 
    (2)设计递归探索函数,每一种可能都是一种if,其约束条件就是 探索是否超越边界and 探索位置的值是否是所需

    (1)适用范围:需要找出全部解或者最优解 
    (2)有组织的搜索 
    (3)探索解空间树

     

     

    思路

    1.bool型hasPath函数,参数:矩阵字符串const char*,矩阵行数int ,矩阵列数int,路径字符串const char*,返回值bool

    1.1如果矩阵为空,或者路径为空,则返回false
    1.2从路径第一个字符开始

    1.3动态分配一个bool矩阵标记是否访问过这个格子并初始化。
    1.4从矩阵的任意位置作为起点开始搜索
            1.4.1如果搜索函数为真,则返回真             
    1.5释放bool矩阵
    1.6返回默认值false
      

    2.bool型递归搜索函数,参数:矩阵字符串const char*,第row行int,第col列int,矩阵行数int,矩阵列数int,路径字符串const char*,访问矩阵数组bool*。

    2.1 如果到达了路径最末尾,就返回真。

    2.2 定义一个bool变量,标志该位置的上下左右是否存在一个字符满足路径下一个字符,并初始化为false

    2.3判断范围:1.数组越界row<rows,row>=0;2.值相等;3.未曾访问

    2.3.1 假设这个路径可以通过,路径++

    2.3.2 更新访问矩阵

    2.3.3更新hasPath,访问上下左右,调用递归函数,

    2.3.4检查hasPath,如果没有符合到达终点的路径,就返回上个路径,并更新访问矩阵

    2.4 搜索函数返回hasPath的值,默认是false,如果到达路径终点,就可以在前面的if中跳出。

     

     

    代码

    class Solution {
    public:
    
        //bool型hasPath函数,参数:矩阵字符串const char*,矩阵行数int ,矩阵列数int,路径字符串const char*,返回值bool
        bool hasPath(const char* matrix,int rows,int cols,const char* str)
        {
            //如果矩阵为空,或者路径为空,则返回false
            if(matrix==nullptr||rows<1||cols<1||str==nullptr)
                return false;
            
            //从路径第一个字符开始
            int pathLength=0;
                
            //动态分配一个bool矩阵标记是否访问过这个格子并初始化。
            bool* visited=new bool[rows*cols];
            memset(visited,0,rows*cols);
            
            //从矩阵的任意位置作为起点开始搜索
            for(int row=0;row<rows;row++)
            {
                for(int col=0;col<cols;col++)
                {
                    if(hasPathCore(matrix,row,col,rows,cols,str,visited,pathLength))//如果搜索函数为真,则返回真
                        return true;
                }
            }
              delete[] visited;//释放bool矩阵
              return false;
        }
    
      
    
        //bool型递归搜索函数,参数:矩阵字符串const char*,第row行int,第col列int,矩阵行数int,矩阵列数int,
                                //路径字符串const char*,访问矩阵数组bool*,
        bool hasPathCore(const char* matrix,int row,int col,int rows,int cols,
                         const char* str,bool* visited,int& pathLength)
        {
            if(str[pathLength]=='')
                return true;//如果到达了路径最末尾,就返回真。
            
            bool hasPath=false;//定义一个bool变量,标志该位置的上下左右是否存在一个字符满足路径下一个字符,并初始化为false
            
            //判断范围
           //1.数组越界row<rows,row>=0
            //2.值相等
            //3.未曾访问
            if(row<rows&&col<cols&&col>=0&&row>=0&&str[pathLength]==matrix[cols*row+col]&&!visited[cols*row+col])
            {
                //假设这个路径可以通过,路径++
                pathLength++;
                //更新访问矩阵
                visited[row*cols+col]=true;
                
                //更新hasPath,访问上下左右,调用递归函数,
                hasPath=hasPathCore(matrix,row-1,col,rows,cols,str,visited,pathLength)||//上
                    hasPathCore(matrix,row+1,col,rows,cols,str,visited,pathLength)||//下
                    hasPathCore(matrix,row,col-1,rows,cols,str,visited,pathLength)||//左
                    hasPathCore(matrix,row,col+1,rows,cols,str,visited,pathLength);//右
                
                //检查hasPath,如果没有符合到达终点的路径,就返回上个路径,并更新访问矩阵
                if(!hasPath)
                {
                    pathLength--;
                    visited[cols*row+col]=false;
                }
                
            }
            
            //搜索函数返回hasPath的值,默认是false,如果到达路径终点,就可以在前面的if中跳出。
            return hasPath;
        }
    };

    核心伪代码 

    方法1 使用函数内调用,则计算count需要 global 变量

    def f(self,参数):
        "需要内容的布局"
    
        def f1(参数):
            "需要的比较复杂的条件"
    
        def f2(参数):
            if "跳出条件1":
                retrun
            if "跳出条件2":
                retrun
    
            "四个方向的探索"
            f2(r+1,c)
            f2(r-1,c)
            f2(r,c+1)
            f2(r,c-1)
    
        return '结果' 

    方法二:采用函数外,就是类下不同方法之间的调用。 
    不需要全局

    class Solution():
        def Path(self,参数):
            "函数布局,产生随机矩阵,"
            # 调用同类下方法,返回所需值
            self.Find_path(参数)
            # 对所需值进行再处理
            return 结果
    
        def PD_K(self,参数):
        "将复杂约束条件设定"
    
        def Find_path(self,参数):
            "对四个位置进行探索,并对所走路径填1"
            对起始位置[0][0]设置为1
            # 如果采用方法之间的调用,则需要将将约束条件融合
            if j+1<n and self.PD_K(参数) and 标记位:
              对走过位置标记
                return self.Find_path(参数)
            elif 四个位置讨论
            else:
                return 所需结果 
  • 相关阅读:
    FreeMark教程
    Intellij IDEA 创建Web项目并在Tomcat中部署运行
    catalina.home和catalina.base这两个属性的作用
    如何用javac 和java 编译运行整个Java工程
    Java中Properties类的操作
    注册邮箱验证激活技术
    commons-logging的使用
    Windows下安装GDB
    BM算法
    Intellij IDEA 部署 项目在tomcat 原理
  • 原文地址:https://www.cnblogs.com/lightmare/p/10428845.html
Copyright © 2020-2023  润新知