『LeetCode|每日一题』---->单词搜索

作者简介:

👨‍🎓一位20级的计科专业的新手,请各位大佬多多指教 

🏡个人主页:XiaoChen_Android 

📚学习专栏:力扣专栏

🕒发布日期:2022/8/6


 『LeetCode|每日一题』单词搜索

 1.每日一题

原文链接--->点我

2.解题思路 

        2.1 思路分析

        此题可以用dfs解决也可以用回溯法解决,我选择了回溯法,它只是比dfs多了一步--撤销修改节点访问状态

        S1:回溯部分的核心传参就是网格的位置i和j,能继续往下找字母需满足以下几个条件:

                1.不能越界;

                2.还没有找全单词所有的字母,即find的值还是false(find定义为全局变量以便于修改它的值);

                3.(i,j)这个点没有被访问过;

                4.当前字母和目标字母应相等。

                (读者可仔细想一下这几个条件,只有满足这几个条件才有继续回溯的必要)

        S2:判断结束条件---当标志位flag = word.length() - 1时,说明刚好找到这个单词,则结束回溯;

        S3:由于每个点有四个方向可以走,所以分四种情况,(i + 1 , j) (i - 1 , j) (i , j + 1) (i , j - 1),这四种情况应都尝试;

        S4:最后通过find的值来判断能否找到该字母

        2.2 核心代码(回溯)

//flag: 记录目标单词的字符索引,只有棋盘格字符和flag指向的字符一致时,才有机会继续搜索接下来的字符;如果flag已经过了目标单词的尾部了,那么便说明找到目标单词了
    private static void back(int i,int j,String word,char[][] board,boolean[][] used,int flag){
        //超出边界、已经访问过、单词已找到、找到的字符和目标字符不相等则直接返回
        if(i < 0 || i >= board.length || j < 0 || j >= board[0].length || used[i][j]
        || find || word.charAt(flag) != board[i][j])  return ;

        //如果flag == word.length() - 1,则说明已经找到了
        if(flag == word.length() - 1){
            find = true;
            return ;
        }

        //遍历四个方向
        used[i][j] = true;
        back(i + 1,j,word,board,used,flag + 1);
        back(i - 1,j,word,board,used,flag + 1);
        back(i,j + 1,word,board,used,flag + 1);
        back(i,j - 1,word,board,used,flag + 1);
        //撤销已访问
        used[i][j] = false;
    }

        2.3 全部代码

class Solution {
    static boolean find; 
    public boolean exist(char[][] board, String word) {
        if(board == null) return false;
        int r = board.length;
        int c = board[0].length;
        boolean[][] used = new boolean[r][c]; //记录点有没有被访问
        int flag = 0;
        find = false;
        //开始遍历
        for(int i = 0; i < r; i++){
            for(int j = 0; j < c; j++){
                back(i,j,word,board,used,flag);
            }
        }
        return find;

    }
    //flag: 记录目标单词的字符索引,只有棋盘格字符和flag指向的字符一致时,才有机会继续搜索接下来的字符;如果flag已经过了目标单词的尾部了,那么便说明找到目标单词了
    private static void back(int i,int j,String word,char[][] board,boolean[][] used,int flag){
        //超出边界、已经访问过、单词已找到、找到的字符和目标字符不相等则直接返回
        if(i < 0 || i >= board.length || j < 0 || j >= board[0].length || used[i][j]
        || find || word.charAt(flag) != board[i][j])  return ;

        //如果flag == word.length() - 1,则说明已经找到了
        if(flag == word.length() - 1){
            find = true;
            return ;
        }

        //遍历四个方向
        used[i][j] = true;
        back(i + 1,j,word,board,used,flag + 1);
        back(i - 1,j,word,board,used,flag + 1);
        back(i,j + 1,word,board,used,flag + 1);
        back(i,j - 1,word,board,used,flag + 1);
        //撤销已访问
        used[i][j] = false;
    }
}

 🍁 类似题目推荐:

1.剑指offer专项练习

2.基础算法无论在研究生面试还是求职面试都是十分重要的一环,这里推荐一款算法练习资源:LeetCode;算法题只有多刷勤刷才能保持思路与手感,大家赶紧行动起来吧(温馨提示:常见的面试问答题库也很nice哦)

 如果文章对你有帮助就支持一下噢,新手尝试,如有不好的地方请各位大佬多多指教! 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值