【Depth First Search DFS】Lintcode 121. Word Solitaire II

Lintcode 121. Word Solitaire II

Title description:
Given two words (start and end) and a dictionary, find out all the shortest conversion sequences from start to end.

The transformation rules are as follows:

  1. Only one letter can be changed at a time.
  2. The middle word in the transformation process must appear in the dictionary.

Insert picture description here
Problem-solving idea: first start from the end point to do a BFS, store the distance between each point and the end point in a hash table, and then use the distance obtained from the BFS traversal from the start point to perform DFS to ensure that every step in the middle is close to the end point One step (so as to ensure that no useless work is done) to find all the shortest sequences.

class Solution {
public:
    /*
     * @param start: a string
     * @param end: a string
     * @param dict: a set of string
     * @return: a list of lists of string
     */
    vector<vector<string> > ans;
    vector<vector<string> > findLadders(string start, string end, unordered_set<string> &dict) {
        dict.insert(end);
        int dsize = dict.size(), len = start.length();
        unordered_map<string, vector<string> > next;
        unordered_map<string, int> vis;
        queue<string> q;
        vector<string> path;
        ans.clear();
        q.push(start);
        vis[start] = 0;
        while (!q.empty()) {        //开始bfs
            string s = q.front(); q.pop();
            if (s == end) break;
            int step = vis[s];
            vector<string> snext;
            for (int i = 0; i < len; i++) {			//枚举s的每位
                string news = s;
                for (char c = 'a'; c <= 'z'; c++) {			//枚举替换的每个字母
                    news[i] = c;
                    if (c == s[i] || dict.find(news) == dict.end()) continue;   //如果替换后的新单词不在dict中就跳过
                    auto it = vis.find(news);
                    if (it == vis.end()) {				//如果新字符串不再vis中,执行存入
                        q.push(news);
                        vis[news] = step + 1;   //步数+1即可
                    }
                    snext.push_back(news);     //snext临时保存s的全部下一步方案
                }
            }
            next[s] = snext;					//next[s]保存s的全部下一步方案
        }
        path.push_back(start);
        dfspath(path, next, vis, start, end);		//开始dfs
        return ans;
    }
    void dfspath(vector<string> &path,  unordered_map<string, vector<string> > &next,
                 unordered_map<string, int> &vis, string now, string end){
        if (now == end) ans.push_back(path);
        else {
            auto vec = next[now];
            int visn = vis[now];
            for (int i = 0; i < vec.size(); i++) {			//枚举now的下一步方案
                if (vis[vec[i]] != visn + 1) continue;		
                path.push_back(vec[i]);						//先将枚举的下一步存入路径
                dfspath(path, next, vis, vec[i], end);
                path.pop_back();							//搜索完成后删除
            }
        }
    }
};

Guess you like

Origin blog.csdn.net/phdongou/article/details/113797488