这道题,最想不通的是为什么要给一个一维数组。给了一维数组需要转换二维数组,而且传参的时候,参数巨多,很容易搞错。总体思路是,采用一个bool类型的和原数组等大的数组来保存节点的访问状态,然后遍历原数组,当原数组中有一个元素的值和str的第一个元素相等时,就去继续判断,判断时,需要将matrix中元素的上下左右都判断一遍,如果相等,继续判断该相等元素的上下左右元素,很明显是一个递归的过程。那首先,为了降低问题复杂度,我们先将这个一维数组转换成二维数组来做,这样会清晰很多。代码如下:

public class Solution {
    public boolean hasPath(char[] matrix, int rows, int cols, char[] str) {
        //首先找到第一个字母出现的位置
        if (matrix==null||matrix.length==0||matrix.length<str.length)
            return false;
        char[][] mat=new char[rows][cols];
        int start=0;
        for (int i=0;i<rows;++i){
            for (int j=0;j<cols;++j)
                mat[i][j]=matrix[start++];
        }
        for (int i=0;i<rows;++i){
            for (int j=0;j<cols;++j){
                if (mat[i][j]==str[0]){
                    boolean[][] flag=new boolean[rows][cols];
                    flag[i][j]=true;
                    if (hasPath(mat,flag,str,i,j,1))
                        return true;
                    else
                        flag[pos]=false;
                }
            }
        }
        return false;
    }

    public boolean hasPath(char[][] matrix,boolean[][] flag,char[] str,int startRow,int startCol,int curPos){
        //计算得到当前位置上下左右的位置
        if (curPos==str.length)
            return true;
        //上
        int newPos;
        if (startRow>0){
            newPos=startRow-1;
            if (dealData(matrix,flag,str,newPos,startCol,curPos))
                return true;
        }
        //下
        if (startRow<matrix.length-1){
            newPos=startRow+1;
            if (dealData(matrix,flag,str,newPos,startCol,curPos))
                return true;
        }
        //左
        if (startCol>0){
            newPos=startCol-1;
            if (dealData(matrix,flag,str,startRow,newPos,curPos))
                return true;
        }
        //右
        if (startCol<matrix[0].length-1){
            newPos=startCol+1;
            if (dealData(matrix,flag,str,startRow,newPos,curPos))
                return true;
        }
        return false;
    }

    public boolean dealData(char[][] matrix,boolean[][] flag,char[] str,int startRow,int startCol,int curPos){
        if (matrix[startRow][startCol]==str[curPos]&&!flag[startRow][startCol]){
            flag[startRow][startCol]=true;
            if (hasPath(matrix,flag,str,startRow,startCol,curPos+1))
                return true;
            else
                flag[startRow][startCol]=false;
        }
        return false;
    }
}

有了二维数组的基础,那我们再将一维数组转换成二维数组,就可以了(不得不说,用一维数组变量真多的。。。代码好丑)一维数组的代码如下:

public class Solution {
    public int rows;
    public int cols;
    public int rowCount;
    public boolean hasPath(char[] matrix, int rows, int cols, char[] str) {
        if (matrix==null||matrix.length==0||matrix.length<str.length)
            return false;
        //首先找到第一个字母出现的位置
        this.rows=rows;
        this.cols=cols;
        int rowNum=matrix.length/rows;
        this.rowCount=rowNum;
        for (int i=0;i<rows;++i){
            for (int j=0;j<cols;++j){
                int pos=rowNum*i+j;
                if (matrix[pos]==str[0]){
                    boolean[] flag=new boolean[matrix.length];
                    flag[pos]=true;
                    if (hasPath(matrix,flag,str,i,j,1))
                        return true;
                    else
                        flag[pos]=false;
                }
            }
        }
        return false;
    }

    public boolean hasPath(char[] matrix,boolean[] flag,char[] str,int startRow,int startCol,int curPos){
        //计算得到当前位置上下左右的位置
        if (curPos==str.length)
            return true;
        //上
        int newPos;
        if (startRow>0){
            newPos=startRow-1;
            if (dealData(matrix,flag,str,newPos,startCol,curPos))
                return true;
        }
        //下
        if (startRow<this.rows-1){
            newPos=startRow+1;
            if (dealData(matrix,flag,str,newPos,startCol,curPos))
                return true;
        }
        //左
        if (startCol>0){
            newPos=startCol-1;
            if (dealData(matrix,flag,str,startRow,newPos,curPos))
                return true;
        }
        //右
        if (startCol<this.cols-1){
            newPos=startCol+1;
            if (dealData(matrix,flag,str,startRow,newPos,curPos))
                return true;
        }
        return false;
    }

    public boolean dealData(char[] matrix,boolean[] flag,char[] str,int startRow,int startCol,int curPos){
        int pos=startRow*this.rowCount+startCol;
        if (matrix[pos]==str[curPos]&&!flag[pos]){
            flag[pos]=true;
            if (hasPath(matrix,flag,str,startRow,startCol,curPos+1))
                return true;
            else
                flag[pos]=false;
        }
        return false;
    }
}

上面的代码中,最最重要的是,当条件不符合时,要将flag恢复为false,以免影响后面的判断