Leetcode 79. Word Search

来源:互联网 发布:湖南软件 编辑:程序博客网 时间:2024/06/06 04:51

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.

s思路:
1. 直接的方法是:dfs,对每个位置,访问上下左右adjacent position, 每次访问为防止重复访问来时的位置,即:上层已经访问过的地方,一定要标记,下层不能再访问。所以还需要一个和矩阵相同尺寸的矩阵来标记是否访问。
2. DFS固然实现功能上是没错的,但是在leetcode上出现TLE,原因:大量重复计算!例如:

这里写图片描述
查找”aaaaaaaaaaaaaaaaaaaa”。从[0,0]处的a开始查询,查询经过[1,2]处的a,到最后的b,发现没找到,然后尝试其他路径同样经过[1,2],也就是说,从[1,2]到b计算了多次,因为从a到[1,2]的路径有多条。如何减少重复呢?如何把计算结果保存?
3. 最后参考之前做的,不单独用一个used[m][n]来保持是否访问的信息,直接每次把使用过的位置,替换成一个非字母符号,例如:’*’即可,这样就不会访问已经访问过的上层节点,免去了大量的矩阵传递!也没有TLE! 这样做的原因:考虑recursive不同层次的数据的独立性,上层数据在下层不会被使用!

//方法1:dfs。功能正确了,但在以下输入TLE了//["aaaa","aaaa","aaaa","aaaa","aaab"]//"aaaaaaaaaaaaaaaaaaaa"//class Solution {public:    bool helper(vector<vector<char>>& board,vector<vector<bool>> used, vector<vector<int>>&dir,string word,int pos,int x,int y){        if(pos==word.size()) return true;        if(x<0||x>=board.size()||y<0||y>=board[0].size()||used[x][y]||word[pos]!=board[x][y])            return false;        used[x][y]=1;        for(int i=0;i<4;i++){            if(helper(board,used,dir,word,pos+1,x+dir[i][0],y+dir[i][1]))                return true;        }        used[x][y]=0;        return false;       }    bool exist(vector<vector<char>>& board, string word) {        //        int m=board.size();        if(m==0) return false;        int n=board[0].size();        vector<vector<int>> dir={{0,1},{0,-1},{1,0},{-1,0}};        vector<vector<bool>> used(m,vector<bool>(n,0));        for(int i=0;i<m;i++){            for(int j=0;j<n;j++){                if(helper(board,used,dir,word,0,i,j))                    return true;                    }            }        return false;    }};//方法2:空间复用,不用visited矩阵,每次使用过一个节点,在进入下一层遍历之前,把这个节点“藏”起来,等recursive回来后,在还原!妙!class Solution {public:    bool helper(vector<vector<char>>& board, vector<vector<int>>&dir,string word,int pos,int x,int y){        if(pos==word.size()) return true;        if(x<0||x>=board.size()||y<0||y>=board[0].size()||word[pos]!=board[x][y])            return false;        char cur=board[x][y];        board[x][y]='*';        for(int i=0;i<4;i++){            if(helper(board,dir,word,pos+1,x+dir[i][0],y+dir[i][1]))                return true;        }        board[x][y]=cur;        return false;       }    bool exist(vector<vector<char>>& board, string word) {        //        int m=board.size();        if(m==0) return false;        int n=board[0].size();        vector<vector<int>> dir={{0,1},{0,-1},{1,0},{-1,0}};        //vector<vector<bool>> used(m,vector<bool>(n,0));        for(int i=0;i<m;i++){            for(int j=0;j<n;j++){                if(helper(board,dir,word,0,i,j))                    return true;                    }            }        return false;    }};
0 0
原创粉丝点击