(算法)单词搜索————<递归>

1. 题⽬链接:79.单词搜索

2. 题⽬描述:

3. 解法:

算法思路:

我们需要假设每个位置的元素作为第⼀个字⺟,然后向相邻的四个⽅向进⾏递归,并且不能出现重复 使⽤同⼀个位置的元素。通过深度优先搜索的⽅式,不断地枚举相邻元素作为下⼀个字⺟出现的可能 性,并在递归结束时回溯,直到枚举完所有可能性,得到正确的结果。

递归函数设计:bool dfs(int x, int y, int step, vector>& board, string word,  vector>& vis, int &n, int &m, int &len)

参数:x(当前需要进⾏处理的元素横坐标),y(当前需要进⾏处理的元素横坐标),step(当前已 经处理的元素个数),word(当前的字符串状态);

返回值:当前坐标元素作为字符串中下标step的元素出现是否可以找到成⽴的字符串。

函数作⽤:判断当前坐标的元素作为字符串中下标step的元素出现时,向四个⽅向传递,查找是否存 在路径结果与字符串相同。

递归函数流程:

1. 遍历每个位置,标记当前位置并将当前位置的字⺟作为⾸字⺟进⾏递归,并且在回溯时撤回标记。

2. 在每个递归的状态中,我们维护⼀个步数step,表⽰当前已经处理了⼏个字⺟。

        ◦ 若当前位置的字⺟与字符串中的第step个字⺟不相等,则返回false。

        ◦ 若当前step的值与字符串⻓度相等,表⽰存在⼀种路径使得word成⽴,返回true。

3. 对当前位置的上下左右四个相邻位置进⾏递归,若递归结果为true,则返回true。

4. 若相邻的四个位置的递归结果都为false,则返回false。

        • 特别地,如果使⽤将当前遍历到的字符赋值为空格,并在回溯时恢复为原来的字⺟的⽅法,则在递 归时不会重复遍历当前元素,可达到不使⽤标记数组的⽬的。  

C++算法代码: 

class Solution
{
public:
    bool t[10][10] = { false };  //状态数组
    int dx[4] = { 1,0,-1,0 };
    int dy[4] = { 0,1,0,-1 };
    bool dfs(vector<vector<char>>& board, string word, int x, int y, int s)
    {
        //出口
        if (s == word.size())
        {
            return true;
        }
        //找数
        for (int i = 0; i < 4; i++)
        {
            //改变后临时参数
            int X = x + dx[i], Y = y + dy[i];
            //合法判断
            if (X < 0 || X >= board.size() || Y < 0 || Y >= board[0].size() || t[X][Y])
            {
                continue;
            }
            //找到数据
            if (board[X][Y] == word[s])
            {
                t[X][Y] = true;
                if (dfs(board, word, X, Y, s + 1) == true)
                {
                    t[X][Y] = false;
                    return true;
                }
                else
                {
                    t[X][Y] = false;
                    continue;
                }
            }
        }
        //没找到则不符合,返回上一层
        return false;
    }
    bool exist(vector<vector<char>>& board, string word)
    {
        //获取开始地址
        for (int i = 0; i < board.size(); i++)
        {
            for (int j = 0; j < board[0].size(); j++)
            {
                if (board[i][j] == word[0])
                {
                    t[i][j]=true;
                    //如果找到了则返回true,没有的话恢复现场继续找
                    if(dfs(board,word,i,j,1)==true)
                    {
                        return true;
                    }
                    t[i][j]=false;
                }
            }
        }
        //一直没有找到则其中没有单词
        return false;
    }
};

Java算法代码:

class Solution
{
	boolean[][] vis;
	int m, n;
	char[] word;
	public boolean exist(char[][] board, String _word)
	{
		m = board.length; n = board[0].length;
		word = _word.toCharArray();
		vis = new boolean[m][n];
		for (int i = 0; i < m; i++)
			for (int j = 0; j < n; j++)
			{
				if (board[i][j] == word[0])
				{
					vis[i][j] = true;
					if (dfs(board, i, j, 1)) return true;
					vis[i][j] = false;
				}
			}
		return false;
	}
	int[] dx = { 0, 0, 1, -1 };
	int[] dy = { 1, -1, 0, 0 };
	public boolean dfs(char[][] board, int i, int j, int pos)
	{
		if (pos == word.length)
		{
			return true;
		}
		// 上下左右去匹配 word[pos] 
		// 利⽤向量数组,⼀个 for 搞定上下左右四个⽅向 
		for (int k = 0; k < 4; k++)
		{
			int x = i + dx[k], y = j + dy[k];
			if (x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] && board[x][y]
				== word[pos])
			{
				vis[x][y] = true;
				if (dfs(board, x, y, pos + 1)) return true;
				vis[x][y] = false;
			}
		}
		return false;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

课堂随笔

感谢支持~~~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值