【原创】leetCodeOj --- Word Ladder II 解题报告 (迄今为止最痛苦的一道题)

原题地址:

https://oj.leetcode.com/submissions/detail/19446353/

 

题目内容:

Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from start to end, such that:

  1. Only one letter can be changed at a time
  2. Each intermediate word must exist in the dictionary

For example,

Given:
start = "hit"
end = "cog"
dict = ["hot","dot","dog","lot","log"]

Return

  [
    ["hit","hot","dot","dog","cog"],
    ["hit","hot","lot","log","cog"]
  ]

 

Note:

  • All words have the same length.
  • All words contain only lowercase alphabetic characters.

 

方法:

在这里我分享下做这道题的心路,不,思路历程。

 

首先第一时间想到BFS,打算正常BFS,但是跟一般的BFS标记结点时不一样,由于可能通过不同路径到达,所以入队前不能标记结点,而是出队时扩展子结点前标记。

结果:TLE

 

然后考虑到,A、B、C、D到能某个结点,比如说F时,可能会重复计算F到终点的路径。考虑先BFS一次求出最短路径作为fullstep的参数,然后以类似动态规划的思路来记录下子问题的结果。其中具体的实现非常的复杂,同样的点,必须在固定的步数内才算有解。

结果:TLE

 

又想到,用unordered_set或者unordered_map装字符串,计算hash值时要遍历整个字符串,这个时候不如整数快。于是,就想到不记录字符串,而记录字符串的地址。字符串在从输入获得的set中。由于int损失了精度,就用long long来存。

结果:TLE

 

没办法了,想到返回子问题解的时候返回的是整个vector,有复制过程,那就换,换成指针,不复制整个vector了。

结果:TLE

 

干,那就提前建图!提前建好图,在图上做这一坨玩意,就不用老是重复拿26个字母穷举所有位置的情况了!

结果:TLE

 

最后的最后的最后,有点想放弃了,在意识模糊的情况下,就采用了提前建图 + BFS的思路。

结果居然TM AC了!

 

全部代码:

class Solution {

public:
    unordered_map<long long,vector<long long>> map; // 提前建图
    unordered_set<long long> mark; // 标记某个点是否已经访问过
    struct node {
        int len;
        node *father;
        string *self;
    };
    
    void generateMap(unordered_set<string> &dict) {
        unordered_set<string> :: iterator it1;
        unordered_set<string> :: iterator it2;
        unordered_set<long long> :: iterator it3;
        unordered_set<long long> used;
        for (it1 = dict.begin(); it1 != dict.end(); ++ it1) {
            vector<long long> tmp;
            map[(long long) & (*it1)] = tmp;
        }
        for (it1 = dict.begin(); it1 != dict.end(); ++ it1) {
            string *now = (string *) & (*it1);
            used.insert((long long) now);
            for (int i = 0; i < (*now).size(); ++ i) {
                char pre = (*now)[i];
                for (int j = 'a'; j <= 'z'; ++ j) {
                    if (j == pre)
                        continue;
                    (*now)[i] = j;
                    it2 = dict.find(*now);
                    if (it2 != dict.end()) {
                        it3 = used.find((long long) & (*it2));
                        if (it3 == used.end()) {
                            map[(long long) now].push_back((long long) & (*it2));
                            map[(long long) & (*it2)].push_back((long long) now);
                        }
                    }
                }
                (*now)[i] = pre;
            }
        }
    }
    
    vector<string> generateVector(node *tmp) {
        vector<string> res;
        while (tmp) {
            res.push_back(*(tmp->self));
            tmp = tmp->father;
        }
        return res;
    }
    
    vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
        generateMap(dict);
        queue<node> myque;
        unordered_set<string> :: iterator it1;
        vector<vector<string>> res;
        vector<node> tmp;
        node startnode;
        it1 = dict.find(end);
        startnode.len = 1;
        startnode.father = NULL;
        startnode.self = (string *) & (*it1);
        myque.push(startnode);
        it1 = dict.find(start);
        string *fin = (string *)&(*it1);
        while (!myque.empty()) {
            node now = myque.front();
            node *fa = new node;
            *fa = now;
            if (now.self == fin) {
                vector<string> lst = generateVector(fa);
                res.push_back(lst);
                int limit = now.len;
                myque.pop();
                while (!myque.empty()) {
                    node last = myque.front();
                    if (last.self == fin && last.len == limit) {
                        lst = generateVector(&last);
                        res.push_back(lst);
                    }
                    myque.pop();
                }
                break;
            }
            mark.insert((long long)(now.self));
            vector<long long> *vecptr = &map[(long long)(now.self)];
            for (int i = 0; i < (*vecptr).size(); ++ i) {
                unordered_set<long long> :: iterator it2 = mark.find((*vecptr)[i]);
                if (it2 == mark.end()) {
                    node child;
                    child.len    = now.len + 1;
                    child.father = fa;
                    child.self   = (string *)(*vecptr)[i];
                    myque.push(child);
                }
            }
            myque.pop();
        }
        return res;
    }
};

  

后记:

之前那个BFS + 回溯 + DP的方法没能AC太可惜了,我那里指针玩的6得自己都怕,唉。。

posted on 2015-01-24 21:32  shadowmydx'sLab  阅读(199)  评论(0编辑  收藏  举报

导航