leetcode第一刷_Word Break

这种题一看,立马就会想到递归,但直接递归的代价太大了,当字典里的单词长度很小,而单词长度很长时,肯定会超时的。再仔细想一下,是不是每次递归验证都是有必要的呢?如果从i位置开始已经被验证为不行了,那么其他递归分支走到这个位置的时候就不用走了,因为肯定是死胡同。想到了打表,把不行的位置记录下来,速度显著提高。

下面说一点实现的事情,记录一个位置行不行,用map最简单直接,查找速度也快。每次选择步长的时候,不用从0到length,我的做法是先统计一下最长和最小的单词长度,每次验证这个长度就可以了。

代码很简单,一般不会出错:

int mmin = 0x7fffffff, mmax = 0;
map<int, bool> visited;
bool pwordBreak(string &s, int start, unordered_set<string> &dict){
    if(start >= s.length())
        return true;
    if(visited.find(start) != visited.end())
        return visited[start];
    for(int i=mmin;i<=mmax&&start+i<=s.length();i++){
        string sb = s.substr(start, i);
        if(dict.find(sb) != dict.end()){
            if(pwordBreak(s, start+i, dict)){
                visited[start+i] = true;
                return true;
            }else{
                visited[start+i] = false;
            }
        }
    }
    return false;
}

class Solution {
public:
    bool wordBreak(string s, unordered_set<string> &dict) {
        unordered_set<string>::const_iterator it = dict.begin();
        while(it != dict.end()){
            mmin = min(mmin, (int)(*it).length());
            mmax = max(mmax, (int)(*it).length());
            it++;
        }
        visited.clear();
        return pwordBreak(s, 0, dict);
    }
};

leetcode第一刷_Word Break

时间: 2024-10-06 11:11:18

leetcode第一刷_Word Break的相关文章

leetcode第一刷_Word Ladder II

注:本文仅供技术探讨, 研究,测试使用. 这个漏洞是2014年2月4日被发现的, 因为该组件试用范围非常广, 所以该漏洞的影响也非常巨大.通过特制的包含畸形header的http请求,可以导致使用该组件的应用程序进入无限循环从而耗尽CPU等资源并最终崩溃. 最近因为在修补struts1的可操纵classLoader的漏洞(struts2也有该漏洞, 不在本文讨论范围), 所以我就在我建立的struts1的项目上直接做测试,怎么创建struts1的项目不在本文讨论范围之列你可以在这里下载strut

leetcode第一刷_Word Search

这道题之前一直没敢做,没想到前天用递归一遍过了.. 当时为什么想着用递归,而不是dp呢,因为我想到达某个位置的情况有很多,即使从当前位置开始的搜索是已知的,但之前的状态是怎样的也无从得知啊,实话实说,我是不会用dp解这个.. 递归的思路就好说多了,从当前点开始,有上下左右四个位置可以探测,如果探测成功的话,要把当前的位置用其他符号标记出来,以免重复访问.实际上就是DFS嘛,只不过入口多一些. 需要注意的一点是,每个点都可以作为起点,所以这个要穷举一下,否则会漏掉情况的.当然有一种情况走通就可以返

leetcode第一刷_Word Ladder

这道题思路不难,本质就是BFS嘛,从一个单词开始,他的下一层是所有可以一步变到,且从来没变到过得那些string.问题是怎样确定这些可以变到的string呢?有两个条件,一,只能通过上一层的string变化一个数字得到,二,变化之后单词必须在字典中.注意是变化一个字母得到,而不是编辑距离是1,要么就复杂了,情况多了好多好多. 我最开始的思路是建个map,保存所有从开始单词能变化到得单词及这些单词一步能变化到的那些单词.too young too simple, 在一个字典非常大的测试用例上超时了

leetcode第一刷_Permutation Sequence

这道题还挺好的,如果你的思路是每次生成一个全排列,然后累计到k次,那么停下来吧,肯定超时了亲.. 微软今年的笔试题里有一道类似的,我之前已经提到过了,是只有0和1的字符串,求第k个排列是什么样子的.这道题比那个要难一些,但是总体的思路是一样的.假设有n个数要组成排列,求第k个排列.像填表一样,从高位往地位,逐个填写.先考虑有n-1个数要组成排列,最多有(n-1)!种情况,当第n个数加入后,第n个数可以是从1增加到n的,没增加1,所包含的全排列数就会增加(n-1)!,因此,如果用k/(n-1)!,

leetcode第一刷_Unique Paths II

接着上面的问题,如果这个矩阵中有阻塞的障碍,就不能用前面的那种组合数的方法了,因为很多位置实际上是没有路的嘛. 剩下的合理解法只有dp了.跟那个求最小和的非常像,从右下角往前推算,对于一个位置(i, j),它的走法应该是(i+1, j)和(i, j+1)走法的和.对于边界条件还是有一些特殊,最后一行,从右往左,如果是0的话没有问题,等于右侧走法的个数,一旦遇到一个1,那么它以及它左边的走法都必须置成0,你可没有穿墙术. 我觉得题目明确说明了行列的个数,就是在暗示我们可以使用dp的方法,行列个数不

leetcode第一刷_Simplify Path

这道题的思路还是比较清晰的,用栈嘛,麻烦是麻烦在这些层次的细节上.主要有下面几个: ./和/:当前路径,遇到这种,应该将后面的文件夹或文件入栈. ../:上一层路径,遇到这种,应该做一次出栈操作,相当于返回了上一层目录. //:可以直接简化成'/'. 还有下面几个要注意的测试用例: 1. linux的路径名可以含有很多特殊字符,比如"_",".","*"等等,所以要特别注意含有"."的哪些路径名. 2. 在路径最后的..和.是

leetcode第一刷_Minimum Window Substring

好题,字符串,线性时间. 我觉得第一次拿到这个题的人应该不会知道该怎么做吧,要么就是我太弱了..先搞清楚这个题要求的是什么.从一个长字符串中找一个字串,这个字串中的字符完全包含了另一个给定目标串中的字符,且这个字串的长度要求最小.还有一个非常重要的简化,题干指明了要求这种最短字串只有一个,这个限制其实暗示了这道题的整体思路,只要找到一个长串,然后缩减到不能缩减即可. 从题目的要求出发可以发现,这道题对于字符串中字符的顺序是没有要求的,因此可以很自然的想到用hash表来保存目标串中的每个字符的个数

leetcode第一刷_Sort Colors

挺有意思的一道题目,属于我之前没有总结到的情况,他在修改数组的时候用到了第三个指针. 如果是两种颜色的话,大家肯定都会做,直接一头一尾两个指针,扫描到不属于自己同类的就互换.这个题有了第三者,怎样来解决这个问题呢?想一下在一个数组中,怎样才能做到线性时间的修改,必须一次性或者常数性的把当前元素替换到他最终应该待的位置,要么复杂就上去了.那当前元素应该呆在那里呢?如果是0的话,应该呆在数组前面都是0的某个地方,如果是2,应该呆在数组后面都是2的地方.那如果是1呢,应该呆在中间,但是0和2最终在哪只

leetcode第一刷_Rotate Image

这个题该怎么说呢,旋转又要求inplace,一般就是要找到某种规律了,这个还是很明显的,画一下原来的,再画一下旋转之后的,看看原来的跑到什么位置了. 牵扯到四个位置按顺时针方向互换一下位置,发现只要做三次交换就可以实现,好神奇. 最后需要注意调整到什么时候结束,如果n是偶数的话,到n/2就是最里层了,不需要继续旋转.奇数其实也是,正好少了最里面的那个只有一个数的层. class Solution { public: void rotate(vector<vector<int> >