79. 单词搜索【力扣】

题意理解

给定一个矩阵,矩阵是字母组成,对于一个字符串,找到一条字母组成的路径,使得字符串等于路径。

问题分析

回溯法

设计回溯函数,要点是记得有一棵树,回溯是在树上做先序遍历。树的节点是状态变量,树的边是可选的取值,函数设计方法是

1. 函数参数包括状态变量,树的可选取值集

2.函数体分为两部分:1. 终止条件; 2. 递归条件;

3.对于递归的数据,设计时当成黑盒,已经实现了,然后判断已经实现情况下如何后续处理。

4. 复杂回溯逻辑设计扣的很细,每一步干什么,要处理什么事情,都要明确,整体要清晰,流程步骤不能有差,有差就出错,出错还不好定位,要求很高。

5. 对于超时情况,看看有没有复杂中间数据结构,减少新增初始化的情况,尽量保持一个来处理。

其他

此题记忆犹新,是微软面试的题。

能力有高低差别,我聚焦自己的问题,自己的方法怎么改进,而不是看别人的方法,记别人的方法,没有用。背上了还是会忘记。有思考才会有改变。

我不能最优,但我可以跑,我的代码复杂,但我自己理解的很清楚,知道虽然复杂,但是是对的,那就够了。脚踏实地,一步一步来。不管多晚,总能做出自己想要的样子。

0926: 提升性能的一个点,是否访问过不能放在循环里,否则时间超限。

力扣

链接

class Solution {
public:
    bool exist(vector<vector<char>>& board, string word) {
        int ret = 0;
		int x_len = board.size();
		int y_len = board[0].size();
		vector<vector<int>> flag(board.size(), vector<int>(board[0].size(), 0));
        for (int i = 0; i < board.size(); i ++) {
            for (int j = 0; j < board[0].size(); j ++) {
                //cout << "start " << i << '\t' << j << endl;
                string curr = "";
				curr.push_back(board[i][j]);

                ret = helper(board, word, flag, x_len, y_len, curr, i, j);
				if (ret == 1) return true;
            }
        }        
        return false;
    }

    int helper(vector<vector<char>>& board, string& word, vector<vector<int>>& flag, int x_len, int y_len, string& curr, int i, int j) {
        //cout << "we " << curr << '\t' << "next " << i << '\t' << j << endl;
        if (word == curr) {
			//cout << "success" << endl;
            return 1;
        }
        if (word[curr.size() - 1] != curr[curr.size() - 1]) {
            //cout << "match error" << endl;
			return 0;
        }
        int ret = 0;
		flag[i][j] = 1;			
        if (i > 0 && flag[i - 1][j] != 1) {
            //flag[i - 1][j] = 1;
			curr.push_back(board[i - 1][j]);
            ret = helper(board, word, flag, x_len, y_len, curr, i - 1, j);
            if (ret == 1) {
				//flag[i - 1][j] = 0;
                return 1;
            }
            else {
                curr.pop_back();
                //flag[i - 1][j] = 0;
            }
        }
        if (i < x_len - 1 && flag[i + 1][j] != 1) {
            //flag[i + 1][j] = 1;
		    curr.push_back(board[i + 1][j]);
            ret = helper(board, word, flag, x_len, y_len, curr, i + 1, j);
            if (ret == 1) {
				//flag[i + 1][j] = 0;
                return 1;
            }
            else {
                curr.pop_back();
                //flag[i + 1][j] = 0;
            }               
        }
        if (j > 0 && flag[i][j - 1] != 1) {
            //flag[i][j - 1] = 1;
			curr.push_back(board[i][j - 1]);
            ret = helper(board, word, flag, x_len, y_len, curr, i, j - 1);
            if (ret == 1) {
				//flag[i][j - 1] = 0;
                return 1;
            }
            else {
                curr.pop_back();
                //flag[i][j - 1] = 0;
            }
        }
        if (j < y_len - 1 && flag[i][j + 1] != 1) {
            //flag[i][j + 1] = 1;
			curr.push_back(board[i][j + 1]);
			ret = helper(board, word, flag, x_len, y_len, curr, i, j + 1);
            if (ret == 1) {
				//flag[i][j + 1] = 0;
                return 1;
            }
            else {
                curr.pop_back();
                //flag[i][j + 1] = 0;
            }
            
        }
		flag[i][j] = 0;
        return 0;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值