leetcode第一刷_Word Ladder

这道题思路不难,本质就是BFS嘛,从一个单词开始,他的下一层是所有可以一步变到,且从来没变到过得那些string。问题是怎样确定这些可以变到的string呢?有两个条件,一,只能通过上一层的string变化一个数字得到,二,变化之后单词必须在字典中。注意是变化一个字母得到,而不是编辑距离是1,要么就复杂了,情况多了好多好多。

我最开始的思路是建个map,保存所有从开始单词能变化到得单词及这些单词一步能变化到的那些单词。too young too simple, 在一个字典非常大的测试用例上超时了。为什么会超时呢,因为字典很大的时候,大家都能互相变来变去,生成我这个映射后的字典代价很大,因为每次都要验证这个单词跟它后面的所有单词是不是只相差了一个字符,建成了这个映射字典,以后每次还是要在map中查找。

那怎么办?还有一个看似不起眼,其实很关键的条件没有使用,那就是所有的单词的长度都一样!还好英文字母一共26个,而且在set的和map中查找的速度都很快,而且,单词长度都还相同,那么我们就从头开始尝试,每次变换一位,看看变化之后的是不是要求的?如果不是,看看在不在字典中,在字典中且没访问过加入到下一层中。尝试完这一波后,把刚变化的位置恢复,这样保证了每次只有一位不一样。有那么点暴力却行得通。

ac代码:

class Solution {
public:
    int ladderLength(string start, string end, unordered_set<string> &dict) {
        if(start == end)
            return 2;
        if(dict.size()<=0)
            return 0;
        queue<string> que;
        set<string> visited;
        int res = 2, len = start.length();
        que.push(start);
        que.push("");
        bool flag = false;
        string tps(start);
        char tp;
        while(!que.empty()){
            tps = que.front();
            que.pop();
            if(tps == ""){
                if(que.empty()){
                    return 0;
                }else{
                    res++;
                    que.push("");
                    continue;
                }
            }
            for(int i=0;i<len;i++){
                char p = tps[i];
                for(tp=‘a‘;tp<=‘z‘;tp++){
                    tps[i] = tp;
                    if(tps == end)  return res;
                    if(dict.find(tps)!=dict.end()){
                        if(visited.find(tps)==visited.end()){
                            visited.insert(tps);
                            que.push(tps);
                        }
                    }
                }
                tps[i] = p;
            }

        }
        return 0;
    }
};

leetcode第一刷_Word Ladder

时间: 2024-07-31 19:33:25

leetcode第一刷_Word Ladder的相关文章

leetcode第一刷_Word Ladder II

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

leetcode第一刷_Word Search

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

leetcode第一刷_Word Break

这种题一看,立马就会想到递归,但直接递归的代价太大了,当字典里的单词长度很小,而单词长度很长时,肯定会超时的.再仔细想一下,是不是每次递归验证都是有必要的呢?如果从i位置开始已经被验证为不行了,那么其他递归分支走到这个位置的时候就不用走了,因为肯定是死胡同.想到了打表,把不行的位置记录下来,速度显著提高. 下面说一点实现的事情,记录一个位置行不行,用map最简单直接,查找速度也快.每次选择步长的时候,不用从0到length,我的做法是先统计一下最长和最小的单词长度,每次验证这个长度就可以了. 代

leetcode第一刷_Binary Tree Inorder Traversal

递归实现当然太简单,也用不着为了ac走这样的捷径吧..非递归实现还挺有意思的. 树的非递归遍历一定要借助栈,相当于把原来编译器做的事情显式的写出来.对于中序遍历,先要訪问最左下的节点,一定是进入循环后,不断的往左下走,走到不能走为止,这时候,能够从栈中弹出訪问的节点,相当于"左根右"过程的"根",然后应该怎么做呢?想一下中序遍历完根节点之后应该干嘛,对,是走到右子树中继续反复这个过程,可是有一点,假设这个节点不包括右子树怎么办?这样的情况下,下一个应该訪问的节点应该

leetcode第一刷_Sqrt(x)

这道题乍看下来非常简单,实际上要注意的问题非常多. 注意看给出来的函数的接口,返回的是int值,也就是计算结果是个近似值.怎样求呢?难道是从2开始往上算?直到某个值正好接近x?当然不行,肯定超时了.再仔细想一下,对了,有二分法,从最大的开始,每次计算一下平方,如果结果比x大,那么缩短上界,否则提高下界. 思想很正确,下面的问题是最大的那个值是多少?你会毫不犹豫的说出是x啊,x的平方根肯定比x小吧.好,那如果x是INT_MAX呢,你想用什么类型来存储这个平方的结果?而且这样每次减半,也得好一会儿才

leetcode第一刷_Subsets II

要求子集,有非常现成的方法.N个数,子集的个数是2^N,每个元素都有在集合中和不在集合中两种状态,这些状态用[0,pow(2,N)]中每个数来穷举,如果这个数中的第i位为1,说明当前集合中包含源数组中的第i个数. 至于有没有重复的元素,大部分有重复元素的问题,都可以借助一个vis集合,里面存放所有已经求得的集合或者其他形式的解,只有少数题目会超时,哪些问题具体的说. class Solution { public: vector<vector<int> > subsetsWithD

leetcode第一刷_Decode Ways

这道题还挺难的.递归的思路是好想,不过不出意料的超时了. dp嘛.想一下i-1的编码加上第i个编码会怎样,如果加上的这个编码不是0,那么这一位可以独立解码,那长为i的解码个数至少是长为i-1的解码个数.还有呢?如果i-1位是1,可以把i-1位和i位同时解码出来,还有呢?如果i-1位是2而i位是0-6中的数字,也可以同时解码这两位编码.满足这个条件的时候,当前长度的解码个数还要加上i-2时的解码个数. 完全可以用一个数组存放过去的结果,但是很明显,当前的结论只与前一个和前前一个结果有关系.只要用三

leetcode第一刷_Gray Code

说到格雷码,应该没人不知道,具体它有什么用,我还真不是很清楚,我室友应该是专家.生成的规律不是很明显,之前看到帖子讲的,这会儿找找不到了.. 思想是这样的,如果有n位,在第2^(n-1)个编码下面画一条水平线的话,你会发现除了第一位之外,其他位都是关于这条线对称的,如下,以三位格雷码举例: 000 001 011 010 --------------------- 110 111 101 100 很神奇吧,我以前是不知道这个规律的.从一开始的一位格雷码,0,1,开始,每次对称的在上一个前面添加上

leetcode第一刷_Permutation Sequence

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