zoukankan      html  css  js  c++  java
  • 矩阵中的路径

    问题:

      请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 例如

      矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。

    分析:穷举+递归遍历

      (1)遍历二维表:因为可能以任意格子作为起点。

      (2)使用HashSet记录路径中包含的格子:因为题目对格子顺序没有要求,且HastSet的查找效率相对高效。

      (3)递归搜索:4个顶点有2个可能的选择方向,其余格子有4个的选择方向,所以进行下一步选择时,需要控制边界情况。

      (4)结束条件:当前HashSet记录的格子数量等于被搜索字符串的长度

      

    code:

      

     /*
        选择路径起点
         */
        public boolean hasPath(char[] matrix, int rows, int cols, char[] str)
        {
            //是否要进行边界情况处理?
            Set<Integer> keep = new HashSet<>();
            for(int i=0;i<rows;i++){
                for(int j=0;j<cols;j++){
                    if(matrix[i*cols+j]==str[0]){
                        keep.add(i*cols+j);
                        searPath(matrix,i,j,rows,cols,str,keep);
                    }
                    if(keep.size()==str.length){
                        return true;
                    }else{
                        keep.clear();
                    }
                }
            }
            return false;
        }
        /*
        路径的递归搜索
         */
        public void searPath(char[] matrix, int i, int j, int rows, int clos, char[] str, Set<Integer> keep){
            int strIndex = keep.size();
            if(strIndex==str.length){
                return;
            }
            //
            int x = i-1;
            int y = j;
            int curIndex = x*clos+y;
            System.out.println(curIndex);
            if(x>=0 && !keep.contains(curIndex) && str[strIndex] == matrix[curIndex]){
                keep.add(curIndex); 
                Set<Integer> newkeep = new HashSet<>();
                //新的路径,建立新的副本
                newkeep.addAll(keep);
                searPath(matrix,x,y,rows,clos,str,newkeep);
                //找到,拷贝回最初的记录器。同时帮助垃圾
                if(newkeep.size()==str.length){
                    keep.addAll(newkeep);
                    newkeep.clear();
                    newkeep=null;
                    return;
                }
                //没找到,同样需要辅助进行垃圾收集
                newkeep.clear();
                //格子回退
                keep.remove(curIndex);
                newkeep=null;
            }
            //
            x = i;
            y = j-1;
            curIndex = x*clos+y;
            if(y>=0 && !keep.contains(curIndex) && matrix[curIndex] == str[strIndex]){
                keep.add(curIndex);
                Set<Integer> newkeep = new HashSet<>();
                //新的路径,建立新的副本
                newkeep.addAll(keep);
                searPath(matrix,x,y,rows,clos,str,newkeep);
                //找到,拷贝回最初的记录器。同时帮助垃圾
                if(newkeep.size()==str.length){
                    keep.addAll(newkeep);
                    newkeep.clear();
                    newkeep=null;
                    return;
                }
                //没找到,同样需要辅助进行垃圾收集
                newkeep.clear();
                //路径回退
                keep.remove(curIndex);
                newkeep=null;
            }
    
            //
            x = i+1;
            y = j;
            curIndex =x*clos+j;
            if(x<rows && !keep.contains(curIndex) && matrix[curIndex] == str[strIndex]){
                keep.add(curIndex);
                Set<Integer> newkeep = new HashSet<>();
                //新的路径,建立新的副本
                newkeep.addAll(keep);
                searPath(matrix,x,y,rows,clos,str,newkeep);
                //找到,拷贝回最初的记录器。同时帮助垃圾
                if(newkeep.size()==str.length){
                    keep.addAll(newkeep);
                    newkeep.clear();
                    newkeep=null;
                    return;
                }
                //没找到,同样需要辅助进行垃圾收集
                newkeep.clear();
                //路径回退
                keep.remove(curIndex);
                newkeep=null;
            }
    
            //
            x = i;
            y = j+1;
            curIndex =x*clos+y;
            if(y<clos && !keep.contains(curIndex) && matrix[curIndex] == str[strIndex]){
                keep.add(curIndex);
                Set<Integer> newkeep = new HashSet<>();
                //新的路径,建立新的副本
                newkeep.addAll(keep);
                searPath(matrix,x,y,rows,clos,str,newkeep);
                //找到,拷贝回最初的记录器。同时帮助垃圾
                if(newkeep.size()==str.length){
                    keep.addAll(newkeep);
                    newkeep.clear();
                    newkeep=null;
                    return;
                }
                //没找到,同样需要辅助进行垃圾收集
                newkeep.clear();
                //路径回退
                keep.remove(curIndex);
                newkeep=null;
            }
        }
  • 相关阅读:
    ADLINK 8158控制程序-连续运动(VB.NET)
    .NET通信中的同步和异步处理
    Java 数据类型转换(转换成字节型)
    matlab中的三维坐标系与旋转
    maya和Unity中的坐标系旋转
    Android Volley完全解析(一),初识Volley的基本用法
    基于VLC的视频播放器(转载)
    android超快模拟器Ggenymotion的安装和配置
    真机在wifi下调试android程序
    Android图片异步加载框架Android-Universal-Image-Loader
  • 原文地址:https://www.cnblogs.com/dream-flying/p/13023872.html
Copyright © 2011-2022 走看看