zoukankan      html  css  js  c++  java
  • 剑指 Offer 12

    1 题目

    https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof/

    2 题意

    请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。例如,在下面的3×4的矩阵中包含一条字符串“bfce”的路径(路径中的字母用加粗标出)。

    [["a","b","c","e"],
    ["s","f","c","s"],
    ["a","d","e","e"]]

    但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。

    示例 1:

    输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
    输出:true
    

    示例 2:

    输入:board = [["a","b"],["c","d"]], word = "abcd"
    输出:false
    

    提示:

    1 <= board.length <= 200
    1 <= board[i].length <= 200
    

    3 思路

    author's blog == http://www.cnblogs.com/toulanboy/

    本题要求判断图中是否存在一条指定的路径。求起点到终点的问题,我们可以借助深度优先搜索解决。

    具体方案为:
    先找出第0个字符在矩阵中出现的位置,然后基于这个位置判断四周是否存在第1个字符。然后再基于第1个字符判断四周是否存在第2个字符,以此类推,直到找到第n个字符。

    可以发现上述过程实际上都是由相同的子过程组成,只是这些子过程的参数不一样。所以,我们只需写一个函数,负责判断第i个位置附近是否有第i+1字符,然后递归调用即可。

    4 代码

    //author's blog == http://www.cnblogs.com/toulanboy/
    class Solution {
    public:
        int direction[4][2] = {{0, 1}, {0, -1}, {-1, 0}, {1, 0}};//方向偏移量
        bool visit[201][201];//访问标志,避免重复使用同一位置的字符
        //dfs(): 判断(x, y)周围是否有word[pos]。
        bool dfs(int x, int y, int pos, vector<vector<char>>& board, string& word){
            if(pos >= word.size()){
                return true;
            }
            int n = board.size();
            int m = board[0].size();
            for(int i=0; i<4; ++i){//4个方向
                int new_x = x + direction[i][0];
                int new_y = y + direction[i][1];
                //合法性判断
                if(new_x >= 0 && new_x < n && new_y >=0 && new_y < m && visit[new_x][new_y]==false){
                    if(board[new_x][new_y] == word[pos]){//如果(x, y)周围是否有word[pos],
                        visit[new_x][new_y] = true;
                        if(dfs(new_x, new_y, pos+1, board, word)){//那么判断(new_x, new_y)周围是否有word[pos+1]
                            return true;
                        }
                        visit[new_x][new_y] = false;
                    }
                }
            }
            return false;
        }
    
        bool exist(vector<vector<char>>& board, string word) {
            memset(visit, 0, sizeof(visit));
            //先找到第0个字符在矩阵中出现位置,然后基于这个位置找下一位数字
            for(int i=0; i<board.size(); ++i){
                for(int j=0; j<board[i].size(); ++j){
                    if(board[i][j] == word[0]){//如果(i, j)出现了word[0]
                        visit[i][j] = true;
                        if(dfs(i, j, 1, board, word)){//判断(i, j)周围是否有word[1]
                            return true;
                        }
                        visit[i][j] = false;
                    }
                }
            }
            return false;
        }
    };
    
  • 相关阅读:
    esDSLindex管理操作相关
    esDSL系统和集群运维相关
    git无法访问或者git访问超慢解决方案
    Java 多线程的一次整理
    记一次 Java 导出大批量 Excel 优化
    16个经典面试问题回答思路
    B树索引
    在Java中,为什么"100==100"为true,而"1000==1000"为false?
    explain详解
    字符串常量池和基本数据类型的包装类常量池
  • 原文地址:https://www.cnblogs.com/toulanboy/p/13702664.html
Copyright © 2011-2022 走看看