剑指OFFER笔记_12_矩阵中的路径_JAVA实现

题目:矩阵中的路径

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

解题思路

  • 此题利用的方法是回溯法。
  • 这条路径有几个性质。1、不能重复走,这意味着需要一个矩阵来储存每个元素是否已经被路径访问过了。2、在搜索路径的时候,可以选择向四个方向之一踏出一步,所以可以在代码中使用递归,如果某个方向的一步不能成功,则返回上一步。
  • 要注意各种特殊情况的处理。如越界、递归的退出条件。
  • 开头的元素需要在board二维数组中去找,之后调用checkPath函数利用递归对每个方向进行判断。
  • 只要找到一条可以走的路径,就可以直接返回true。

代码

函数主体部分代码

package q12;

/**
 * 请设计一个函数,用来判断一个矩阵中是否存在一条包含某字符串所有字符的路径。
 * 路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向上下左右移动一格。
 * 如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。
 */
public class Solution {
    public boolean exist(char[][] board, String word) {
        //异常控制
        if (board == null || board.length == 0 || board[0].length == 0
                || word == null)
        {
            return false;
        }

        //将待寻找的字符串储存在char数组里
        char[] chars = word.toCharArray();

        //该数组保存当前位置的元素是否已被访问过
        boolean[][] visited = new boolean[board.length][board[0].length];
        for (int i = 0; i < visited.length; i++) {
            for (int j = 0; j < visited[i].length; j++) {
                visited[i][j] = false;
            }
        }
        //该值表示当前查找的char数组下标
        int charsIndex = 0;
        //对board每个元素当成开头进行检索
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[i].length; j++) {
                if(checkPath(board, chars, visited, i, j, charsIndex))
                {
                    return true;
                }
            }
        }
        //若之前没有返回,此时返回false
        return false;
    }

    public boolean checkPath(char[][] board, char[] chars, boolean[][] visited, int i, int j, int charsIndex)
    {
        if (charsIndex == chars.length)
        {
            return true;
        }
        //默认为false
        boolean result = false;

        //如果符合条件
        if(i >= 0 && i < board.length && j >= 0 && j < board[0].length && charsIndex < chars.length &&
            chars[charsIndex] == board[i][j] && !visited[i][j])
        {
            //先前进,visited对应元素置为true
            charsIndex++;
            visited[i][j] = true;

            //向四个方向分别检索
            result = checkPath(board, chars, visited, i+1, j, charsIndex) ||
                    checkPath(board, chars, visited, i-1, j, charsIndex) ||
                    checkPath(board, chars, visited, i, j+1, charsIndex) ||
                    checkPath(board, chars, visited, i, j-1, charsIndex);

            //若四个方向都不可以,返回上一步。
            if(!result)
            {
                charsIndex--;
                visited[i][j] = false;
            }
        }
        //若上面if中result为true,此时则是true,否则为false
        return result;
    }
}

测试部分代码

package q12;

public class TestApp {
    public static void main(String[] args) {
        char[][] board = {  {'a','b','t','g'},
                            {'c','f','c','s'},
                            {'j','d','e','h'}   };
        Solution s = new Solution();
        System.out.println("abfce is: " + s.exist(board, "abfce"));
        System.out.println("'null' is: " + s.exist(board, ""));
        System.out.println("aba is: " + s.exist(board, "aba"));
        System.out.println("bfdjc is: " + s.exist(board, "bfdjc"));
        System.out.println("abtga is: " + s.exist(board, "abtga"));

    }
}

运行结果截图

在这里插入图片描述

LeetCode运行截图

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值