LeetCode 79. Word Search 二维平面使用回溯法

Given a 2D board and a word, find if the word exists in the grid.

The word can be constructed from letters of sequentially adjacent cell, where “adjacent” cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.

For example,
Given board =

[
[‘A’,’B’,’C’,’E’],
[‘S’,’F’,’C’,’S’],
[‘A’,’D’,’E’,’E’]
]

word = “ABCCED”, -> returns true,
word = “SEE”, -> returns true,
word = “ABCB”, -> returns false.

题意

给定一个二维平面的字母和一个单词,看是否可以在这个二维平面上找到该单词。其中找到这个单词的规则是,从一个字母出发,可以横向或者纵向连接二维平面上的其他字母。同一个位置的字母只能使用一次。

思路

  1. 以字符栅格的(0,0)点开始去匹配word[0],当有[i,j]和word[0]相等,那么就继续去找[i,j]周围的四个元素上[i-1,j],右[i,j+1],下[i+1,j],左[i,j-1]。注意这里的坐标并不是笛卡尔坐标系的计算.
  2. 直达以[i,j]为起点的路线中能找到和word全匹配的元素。
  3. 当不匹配,一直回退到[i,j],以[i,j+1]为起点重复1步骤。
    这里写图片描述
    这里写图片描述

代码

class Solution {
private:
    int d[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};
    //相对于某一元素的周围上、右、下、左元素的相对位置。横坐标x表示行极限为m,纵坐标y表示列极限为y
    int m,n;
    vector<vector<bool>> visited;

    bool inArea( int x , int y ){
        //看新坐标是否是合法的
        return x >= 0 && x < m && y >= 0 && y < n;
    }

    // 从board[startx][starty]开始, 寻找word[index...word.size())  
    bool searchWord( const vector<vector<char>> &board, const string& word, int index,
                    int startx, int starty ){

        //assert( inArea(startx,starty) );
        //当word只剩最后一个元素需要匹配时,只需要看该栅格所在的元素是否和word的最后一个元素相等,就不需要判断该栅格的上下左右元素了。
        //相等就说明找到这样的一条路径,不相等就回退到上一层,看上一层元素其余的方向是否满足
        if( index == word.size() - 1 )
            return board[startx][starty] == word[index];

        //如果栅格的[startx][starty]位置元素与word[index]元素相等,那就递归的去看[startx][starty]位置其余方向的元素是否与word[index]相等
        if( board[startx][starty] == word[index] ){
            visited[startx][starty] = true;
            //表示栅格该位置元素已经不能被访问了

            // 从startx, starty出发,向四个方向寻
            for( int i = 0 ; i < 4 ; i ++ ){
                int newx = startx + d[i][0];
                int newy = starty + d[i][1];
                if( inArea(newx, newy) && !visited[newx][newy] &&
                    searchWord( board , word , index + 1 , newx , newy ) )
                    return true;
            }
            //栅格的[startx][starty]周围的元素与word[index+1]元素不行相等,说明此路不通,需要将该位置释放,可能之后会满足要求
            visited[startx][starty] = false;
        }
        return false;
    }
public:
    bool exist(vector<vector<char>>& board, string word) {

        m = board.size();   //栅格有m行
        assert( m > 0 );
        n = board[0].size();  //栅格有n列
        //如果按照矩阵来理解,是MxN
        visited = vector<vector<bool> >(m,vector<bool>(n,false));  
        //当某个元素被访问并且属于word内的元素,将该元素置为true

        //遍历整个栅格,来找以[i,j]为起点,word是否存在,如果存在返回true,不存在继续下一个,index每次都是以0开始
        for( int i = 0 ; i < board.size() ; i ++ )
            for( int j = 0 ; j < board[i].size() ; j ++ )
                if( searchWord( board, word, 0 , i, j) )                
                    return true;

        //当整个栅格完全遍历一遍都没找到完全匹配word,就说明该栅格不含word,返回false
        return false;
    }
};

结果

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值