[leetcode oj]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 =

[
  ["ABCE"],
  ["SFCS"],
  ["ADEE"]
]

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

题目解析:题目要求在一个网格中搜索一条路径,这个路径中的所有字符组成给定的word。如果无法搜索到,就返回false,搜索到就返回true。这个问题需要利用回溯的方法进行搜索。

首先,谈谈回溯搜索方法的一些基本要素:

(1)一个记录遍历足迹的数组

(2)搜索终结的条件

(3)回溯搜索需要传递什么参数。

搜索递归公式:

给定当前的位置(x,y),可以选择的下一个位置(x + i, y + j), 其中要求必须是相邻的,并且在board内。则abs(i) +abs(j) == 1, x + i >=0 && x + i < row && y +j>= 0 && y + j < col。

搜索终止条件:

(1)如果当前指示word中位置的下标>= word.lenght(),则表明已经找到满足条件的路径,返回true.

(2)如果当前位置所有可能的下一个位置都未找到满足条件的路径,返回false.

(3)如果在某个位置搜索下,backtracking返回true,则存在满足条件的路径,终止搜索,返回true.


我作为一个懂得不多的尝试者,最切实的感受是,思路一定要明确,考虑好算法,然后再编程,否则就会浪费很多无谓的时间去找bug。同时,因为对编程语言底层了解的欠缺,会导致浪费大量时间。比如在c++中二维数组的动态分配,并将该数组作为参数传递。其实,这个习惯我看来并不是一个很好的习惯,并且容易因此产生bug。最简单的方法是用vector来代替数组,利用引用的方式传递参数。总之总之,作为一个greenhand,希望能带给和我一样的新手一些帮助。下面是c++下面的实现:

<pre class="html" name="code">class Solution {
public:
	bool static exist(vector<vector<char> > &board, string word) {
		int row = board.size();
		int col = board[0].size();
		if (word.length() == 0 || (unsigned)row * col < word.length())
			return false;
		//declare and initialize indication array
		vector<vector<bool>> mark;
		for (int i = 0; i < row; i++){
			vector<bool> temp;
			for (int j = 0; j < col; j++){
				temp.push_back(false);
			}
			mark.push_back(temp);
		}
		bool result;
		for (int i = 0; i < row; i++){
			for (int j = 0; j < col; j++){
				if (board[i][j] == word.c_str()[0]){
					mark[i][j] = true;
					result = backtracking(board, mark, word, 1, i, j);
					mark[i][j] = false;
					if (result)
						return true;
				}
			}
		}
		return false;
	}
	bool static backtracking(vector<vector<char>> &board, vector<vector<bool>> &mark, string word, int current,int x, int y){
		if ((unsigned)current >= word.length()){
			return true;
		}
		int row = board.size();
		int col = board[0].size();
		bool success = false;
		for (int i = -1; i < 2; i++){
			for (int j = -1; j < 2; j++){
				if (abs(i) + abs(j) == 1){
					if (x + i < row && x + i >= 0 && y + j < col && y + j >= 0){
						if (!mark[x + i][y + j] && board[x + i][y + j] == word.c_str()[current]){
							mark[x + i][y + j] = true;
							success = backtracking(board, mark, word, current + 1, x + i, y + j);
							mark[x + i][y + j] = false;
							if (success)
								return true;
						}
					}
				}
			}
		}
		return false;
	}
};

 



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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值