刷题LeetCode 剑指offer12

本人新手为了面试互联网公司,将刷题做一个记录以及总结,方便之后学习!!

第10道问题 剑指offer 12 为一道中等题

题目:

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

 1.自己思路

遍历board,找到word中字母的开头,依据这个开头进行回溯。若包含分别遍历,反之return false。

class Solution {
    public boolean exist(char[][] board, String word) {
      int m=board.length;
      int n=board[0].length;
      boolean res=false;
      //开始遍历
      for(int i=0;i<m;i++){
          for(int j=0;j<n;j++){
              if(board[i][j]==word.charAt(0)){
                res = deal(board,i,j,word,m,n,0,res);
                if(res){
                    return res;
                }
              }else{
                  continue;
              }
          }
      }
      return res;
    }

    public boolean deal(char[][] board,int  i,int j,String word,int m,int n,int len,boolean res){
        if(len==word.length() && res){//退出
           return true;
        }
       while(len<=word.length()){
        if(i <=m && j+1<=n ){//右移
           if(board[i][j+1]==word.charAt(len+1)){
                res=deal(board,i+1,j,word,m,n,len+1,res);
           }else{
                break;
           }
        }else if(i <=m && j-1>=0){
            if(board[i][j-1]==word.charAt(len+1)){
                res=deal(board,i,j-1,word,m,n,len+1,res);
           }else{
                break;
           }
            
        }else if(i+1 <=m && j<=n){
            if(board[i+1][j]==word.charAt(len+1)){
                 res=deal(board,i+1,j,word,m,n,len+1,res);
           }else{
                break;
           }
           
        }else if(i-1 >=0 && j<=n){
             if(board[i-1][j]==word.charAt(len+1)){
                 res=deal(board,i+1,j,word,m,n,len+1,res);
           }else{
                break;
           }
           
        }
       }
       return false;
    }
}

但是这种方法超时了,也没有解决不可重复遍历一个元素的思想。

结果:

 查找答案分析:

1.需要构建一个boolean的数组来判定是否走过该路径。

2.回溯算法,应用的不够好。

class Solution {
    public boolean exist(char[][] board, String word) {
      int m=board.length;
      int n=board[0].length;
      boolean[][] visited=new boolean[m][n];//新建一个boolean数组,走过设置为true,否则默认为false
      //开始遍历
      for(int i=0;i<m;i++){
          for(int j=0;j<n;j++){
              if(board[i][j]==word.charAt(0)){
                   if(  deal(board,i,j,word,m,n,0,visited)  ){
                       return true;
                    }
               }
             }
       }
      return false;
    }

    public boolean deal(char[][] board,int i,int j,String word,int m,int n,int len,boolean[][] visited){
        if(len == word.length()){//退出条件,len从0开始,最终时为word长度-1但是每一次都len+1了,这里需要对比的为word的长度
            return true;
        }
        boolean res = false;
        if(i<0 ||i>=m ||j<0 ||j>=n ||board[i][j] !=word.charAt(len) || visited[i][j]){
            //i ,j的范围不可超出board的边框,下一个board要与word中的字符相等 同时visited未访问过
            return false;
        }

        visited[i][j] = true;//访问了,设置为true
        //访问下一个
        res = deal(board,i+1,j,word,m,n,len+1,visited) || deal(board,i-1,j,word,m,n,len+1,visited)
              || deal(board,i,j+1,word,m,n,len+1,visited)  || deal(board,i,j-1,word,m,n,len+1,visited);

        visited[i][j] = false;//不访问,设置为false
        return res;
    
    }//end deal

}

结果:

总结:
1.遇到多个方向查找的题目,尝试回溯算法。

2.判定是否走过某个路径,需要增加额外的空间进行处理。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值