ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

单词拆分(Leetcode-139)-记忆化搜索&DFS

2021-07-20 15:02:26  阅读:209  来源: 互联网

标签:index return int 位置 DFS vis depth 139 Leetcode


题目

知识点

  • 记忆化搜索

思路

  • 虽然是一个个单词,但本质可以看作是路径寻找问题,字符串s每个字符相当于一个路径节点,问是否能从以第一个字母为节点开始,找到最后一个字符结束的路径,如下为例子:

    输入: s = “applepenapple”, wordDict = [“apple”, “pen”]
    输出: true
    "apple"相当于0->4有一条路,8->12有一条路(单词可重复使用)
    "pen"相当于5->7有一条路

  • 那么,在上述的例子中,我们可以找到一条路径满足问题,即0->4 再到 5->7 再到 8->12

  • 问题在于如何获得每个单词能够产生的“路径”。注意,例如上述中的例子apple可以出现两次(因为相同单词可以使用多次)。因此,在开始的时候先构建路径图。我们对于一个单词,需要从头到尾搜索一遍(Line 29-46),检索在 s 中的位置。因为 find() 只能找到第一个子串,所以用 while 设置循环,每次寻找子串开始位置向后一位继续查找。我使用了 map<int, vector<int>> m 记录了所有可能走的路径,在后面DFS找路径的时候,m[当前位置] 即可获得这个位置出发,所有能够到达的位置。

  • 但是,但是… 单一这样的方法只能过30+数据,不能过全部的数据,因此我们还需要进行优化。

记忆化搜索

  • 其实就是动态规划那味…
  • 使用 int vis[1000] 去记录当前这个位置是否被访问过(-1 - 未访问,0 - 访问过但走不通,1-访问了走得通)。即:如果被访问了,当前位置出发是否能够到达。
  • 当然在这道题里找到了就逐层返回true了(可以用两位表示,这里我就直接用 int 类型了)…所以在这题里,vis 就是用于告诉我们该位置已经走过了,是走不通的,别走了别走了!浪费时间(Line 9)
  • Line 14-21 就是向下搜索的过程,如果当前位置可以继续往下走 m.count(depth) ,那我们就一个个向下搜索,如果全部向下走都不行,那我们从该位置出发就是行不通的,因此把这个位置 vis 标记为0 (Line 23)

代码

  • PS:我的方法代码虽然长一点,但是速度好像比一般的更快哈哈~
    在这里插入图片描述
class Solution {
public:
    map<int, vector<int>> m;  // index - 位置
    int ed;
    int vis[1000];

    bool dfs(int depth) {
        int &ans = vis[depth];
        if (ans != -1) return ans;  // 这个depth后续访问已经做过,是走不通的

        if (depth == ed) return true;
        if (depth > ed) return false;

        if (m.count(depth)) {
            for (int i:m[depth]) {
                if (dfs(i + 1)) {
                    ans = 1;  // 这个depth可以走
                    return true;
                }
            }
        }
        ans = 0;
        return false;
    }

    bool wordBreak(string s, vector<string> &wordDict) {
        ed = s.size();
        memset(vis, -1, sizeof(int[1000]));
        for (const string &i:wordDict) {
            int b = 0, index;
            bool end = false;
            while (!end) {
                if (b > s.size()) break;
                index = s.find(i, b);
                if (index != -1) {
                    if (!m.count(index)) {
                        m[index] = vector<int>(1, index + i.size() - 1);
                    } else {
                        m[index].emplace_back(index + i.size() - 1);
                    }
                    b += 1;
                } else {
                    end = true;
                }
            }
        }
        return dfs(0);
    }
};

标签:index,return,int,位置,DFS,vis,depth,139,Leetcode
来源: https://blog.csdn.net/weixin_44855409/article/details/118933992

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有