• 矩阵中的路径


    题目描述

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

    例如

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

    思路

    1、简单记忆化搜索:每次搜索需要重新初始化vis数组
    2、回溯法:vis数组无需重复刷新
    

    时间复杂度O(mn),空间复杂度O(mn)。

    代码

    简单记忆化搜索

    public class Solution {
        int row;
        int col;
        private boolean[][] vis;
        private boolean check(char[] mat, int x, int y, char[] str, int step) {
            if(x < 0 || x >= row || y < 0 || y >= col) {
                return false;
            }
            if(mat[x*col+y] == str[step] && !vis[x][y]) {
                if(step + 1 == str.length) {
                    return true;
                }
                vis[x][y] = true;
                return check(mat, x + 1, y, str, step + 1) ||
                        check(mat, x - 1, y, str, step + 1) ||
                        check(mat, x, y + 1, str, step + 1) ||
                        check(mat, x, y - 1, str, step + 1);
            }
            return false;
        }
        public boolean hasPath(char[] matrix, int rows, int cols, char[] str) {
            if(matrix == null || matrix.length == 0 || rows < 1 || cols < 1 || str == null || str.length == 0) {
                return false;
            }
            row = rows;
            col = cols;
            for(int i = 0; i < rows; i++) {
                for(int j = 0; j < cols; j++) {
                    vis = new boolean[rows][cols];
                    if(check(matrix, i, j, str, 0)) {
                        return true;
                    }
                }
            }
            return false;
        }
    }
    

    回溯法

    public class Solution {
        int row;
        int col;
        private boolean[][] vis;
        private boolean check(char[] mat, int x, int y, char[] str, int step) {
            if(x < 0 || x >= row || y < 0 || y >= col || mat[x*col+y] != str[step] || vis[x][y]) {
                return false;
            }
            if(step + 1 == str.length) {
                return true;
            }
            vis[x][y] = true;
            if(check(mat, x + 1, y, str, step + 1) ||
                    check(mat, x - 1, y, str, step + 1) ||
                    check(mat, x, y + 1, str, step + 1) ||
                    check(mat, x, y - 1, str, step + 1)) {
                return true;
            }
            vis[x][y] = false;
            return false;
        }
        public boolean hasPath(char[] matrix, int rows, int cols, char[] str) {
            if(matrix == null || matrix.length == 0 || rows < 1 || cols < 1 || str == null || str.length == 0) {
                return false;
            }
            row = rows;
            col = cols;
            vis = new boolean[rows][cols];
            for(int i = 0; i < rows; i++) {
                for(int j = 0; j < cols; j++) {
                    if(check(matrix, i, j, str, 0)) {
                        return true;
                    }
                }
            }
            return false;
        }
    }
    

    笔记

    当记忆化数组不可以重用时,考虑回溯。

  • 相关阅读:
    sqlserver的排序
    tomcat虚拟目录!
    tomcat虚拟主机配置!
    深度优先搜索算法
    java是什么?
    tomcat服务器jar管理!
    广度优先搜索算法
    简单web服务器
    cascade="alldeleteorphan"时容易出现的一个异常
    Hibernate级联删除的一个错误
  • 原文地址:https://www.cnblogs.com/ustca/p/12764070.html
Copyright © 2020-2023  润新知