• 矩阵中的路径


    题目描述

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

    例如

    矩阵中包含一条字符串"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;
        }
    }
    

    笔记

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

  • 相关阅读:
    chkdsk磁盘修复命令工具怎么用,怎样运行chkdsk工具修复?
    phpMyAdmin 尝试连接到 MySQL 服务器,但服务器拒绝连接。您应该检查配置文件中的主机、用户名和密码
    APiCloud真机调试需要注意的几个问题
    QQ个人文件夹中的文件被占用,解决办法
    PHPExcel读取excel文件
    数据挖掘与机器学习
    什么是数据挖掘?
    数据挖掘相关的10个问题
    PhpStorm 快捷键大全 PhpStorm 常用快捷键和配置
    VirtualBox提示:错误,创建一个新任务失败,被召者解决办法
  • 原文地址:https://www.cnblogs.com/ustca/p/12764070.html
Copyright © 2020-2023  润新知