力扣79题单词搜索+深度优先搜索

本文详细介绍了一种解决LeetCode单词搜索问题的深度优先搜索算法。通过对给定的二维网格和单词,查找单词是否能在网格中按字母顺序,通过相邻单元格的字母构成。文章提供了详细的算法解释和C++代码实现。

问题

给定一个二维网格和一个单词,找出该单词是否存在于网格中。

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

示例:

board =
[
  ['A','B','C','E'],
  ['S','F','C','S'],
  ['A','D','E','E']
]

给定 word = "ABCCED", 返回 true.
给定 word = "SEE", 返回 true.
给定 word = "ABCB", 返回 false.

题目链接:https://leetcode-cn.com/problems/word-search

解法:

深度优先算法

link: https://leetcode-cn.com/problems/word-search/solution/zai-er-wei-ping-mian-shang-shi-yong-hui-su-fa-pyth/

代码

#include<iostream>
#include<vector>
//#include<algorithm>
using namespace std;
class Solution{
public:
bool cross_exist(vector<vector<char>>& board, string word, pair<int, int> start, int& row, int& col) 
{
	/*
	* 从给出的起始点 start 上下左右 寻找符合条件的单词
	*/
	int p1 = start.first, p2 = start.second;
	char c = word[0];
	if (word.empty() != true) word.erase(word.begin(), word.begin() + 1);
	else return true;
	// 下
	if (p1 != row - 1) {
		pair<int, int> v = { p1 + 1, p2 };
		if (board[v.first][v.second] == c) {
			board[v.first][v.second] = '.';
			bool ans = cross_exist(board, word, v, row, col); // 递归
			board[v.first][v.second] = c;
			if (ans) return true;
		}
	}
	// 上
	if (p1 != 0) {
		pair<int, int> v = { p1 - 1, p2 };
		if (board[v.first][v.second] == c) {
			board[v.first][v.second] = '.';
			bool ans = cross_exist(board, word, v, row, col);
			board[v.first][v.second] = c;
			if (ans) return true;
		}
	}
	// 左
	if (p2 != 0) {
		pair<int, int> v = { p1 , p2 - 1 };
		if (board[v.first][v.second] == c) {
			board[v.first][v.second] = '.';
			bool ans = cross_exist(board, word, v, row, col);
			board[v.first][v.second] = c;
			if (ans) return true;
		}
	}
	// 右
	if (p2 != col - 1) {
		pair<int, int> v = { p1 , p2 + 1 };
		if (board[v.first][v.second] == c) {
			board[v.first][v.second] = '.';
			bool ans = cross_exist(board, word, v, row, col);
			board[v.first][v.second] = c;
			if (ans) return true;
		}
	}
	return false;
}
bool exist(vector<vector<char>>& board, string word) 
{
	int row = board.size();//行数
	int col = board[0].size(); // 列数
	vector<vector<int>> pos1 = {};
	if (word.size() > (row * col)) return false; //如果 string太长,一定是找不到单词的

	// 遍历找第一个字母, 所有结果保存起来
	for (int i = 0; i < row; i++) {
		for (int j = 0; j < col; j++) {
			if (board[i][j] == word[0])
				pos1.push_back({ i,j });
		}
	}

	if (pos1.empty()) return false; // 找不到第一个字母,自然是找不到单词的
	else {
		char c = word[0];
		word.erase(word.begin(), word.begin() + 1);
		// 对所有满足第一单词的位置进行遍历 调用cross_exist()
		for (auto x : pos1) {
			pair<int, int> start;
			start.first = x[0];
			start.second = x[1];
			// 修改 board, 防止单词被使用多次
			board[start.first][start.second] = '.';
			bool ans = cross_exist(board, word, start, row, col);
			// 改回来
			board[start.first][start.second] = c;
			if (ans == true) return true;
		}
		return false;
	}
}

};


int main() {
	Solution solv;
	// 测试1
	//vector<vector<char>> board = { {'A','B','C','E'},
	//							     {'S','F','E','S'},
	//							     {'A','D','E','E'} };

	//string word = "CESEEE";

	// 测试2
	vector<vector<char>> board = { {'A','A','A','A'},
							       {'A','A','A','A'},
								   {'A','A','A','A'},
								   {'A','A','A','A'},
							       {'A','A','A','B'} };

	string word = "AAAAAAAAAAAAAAAAAAAA";

	auto ans = solv.exist(board, word);
	cout << ans << endl;
	return 0;

}
### LeetCode 单词搜索解及算法实现 #### 目描述 给定一个 `m x n` 的二维字符网格 `board` 和一个字符串单词 `word`。如果 `word` 存在于网格中,则返回 `true`; 否则,返回 `false`[^3]。 #### 解决方案概述 该问是典型的回溯算法应用案例,在一个二维字符数组中按照指定规则(水平、垂直、对角线)搜索给定单词。通过递归尝试从每一个可能起点出发构建路径来匹配目标单词[^2]。 #### 算法细节 为了高效解决此问, 主要采用深度优先搜索(DFS)配合剪枝策略: - **边界条件处理**: 如果输入为空或者网格尺寸不足以容纳待查单词长度直接返回False. - **辅助函数定义**: 定义内部递归函数用于执行具体搜索逻辑。 - **状态标记机制**: 使用访问标志位记录已走过位置防止重复遍历形成循环. ```cpp class Solution { public: bool exist(vector<vector<char>>& board, string word) { int rows = board.size(); int cols = board[0].size(); for (int i = 0; i < rows; ++i){ for (int j = 0; j < cols; ++j){ if(dfs(board, word, i, j, 0)){ return true; } } } return false; } private: const vector<pair<int,int>> directions{{0,-1},{-1,0},{0,1},{1,0}}; bool dfs(vector<vector<char>>& b, string& w, int r, int c, int idx){ if(idx == w.length()){ return true; } if(r<0 || r>=b.size() || c<0 || c>=b[0].size() || b[r][c]!=w[idx]){ return false; } char temp = b[r][c]; b[r][c]='*'; for(auto& d : directions){ if(dfs(b,w,r+d.first,c+d.second,idx+1)){ return true; } } b[r][c]=temp; return false; } }; ``` 上述C++代码实现了完整的单词搜索功能,其中包含了必要的错误检查以及优化措施以提高性能表现.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值