Hero Pang: Minimum operand

Source: Internet
Author: User

Given two words A and B and A word set Dict, each of which has the same length. We want to change word A to word B through several operations. Each operation can change A letter in the word. At the same time, the new word must be in the given word set Dict. Evaluate the modification method with the minimum number of practical steps.

For example:

Given: A = "hit" B = "cog"

Dict = ["hot", "dot", "dog", "lot", "log"]

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

To convert string A = "hit" into string B = "cog", there are two possibilities:

"Hit"-> "hot"-> "dot"-> "dog"-> "cog ";

"Hit"-> "hot"-> "lot"-> "log"-> "cog ".


My ideas are as follows:

Establish a multi-Cross Tree (similar to a multi-Cross Tree) in the breadth-first mode ). Start from the character given by the start, find all the sets with a letter difference from the dictionary, all are child nodes of the Start character, and put these nodes into a list. Then, for each node N in the list, continue to find all the sets with a letter difference (not including nodes already on the tree and with a depth lower than the current processing layer) as the child node of N. In this way, the multi-Cross Tree is created in the breadth-first mode. Finally, we met word B. After processing this layer, we can reverse the change process from the tree (there may be multiple feasible changes ).

Create a multi-Cross Tree Based on the dictionary given in the example (Add character B to the dictionary first):


Note that:

1 tree is built layer by layer, that is, breadth first, rather than depth first. For example, there are dot and lot on Layer 1. Put dot and lot on the tree first, and then set up Layer 3. Therefore, a secondary list is required to store nodes at each layer. To facilitate the establishment of the next layer.

2. To ensure that no reverse turning occurs during tree creation, the nodes added to the tree need to be marked. In my code, the depth of the initialized nodes is-1, indicates that it has not been added to the tree.

The two branches of the three trees may contain the same child node, for example, from layer 4th to layer 5th. The cog node has two parent nodes, so strictly speaking, this is not a tree ^_^. In addition, the cog has been added to the tree when processing the dog node, but when processing the log node, once again, it seems that there is a 2nd conflict. In fact, it is not because the dog and log are on the same layer. This is required to record all feasible solutions.

4. You do not need to record the child nodes of a node. However, to trace the result, each node must record its own parent node (multiple parent nodes may exist ).

5. Tracing is simple. We use an array to simulate the stack and keep moving from Node B to the parent node, recording all feasible paths.


Let's take a look at the Code. The Code below failed to be submitted by panggo.com. I suggest you leave it blank.

// MinOperationCount. cpp: Defines the entry point for the console application. // # include "stdafx. h "# include <string> # include <vector> # include <map> # include <set> # include <iostream> using namespace std; typedef struct _ NODE {vector <string> vecParentNode; int nDeep; bool isEnd;} NODE, * PNODE; bool IsNear (const string & strDest, const string & strSource) {int nLenDest = strDest. length (); int nLenSource = StrSource. length (); if (nLenSource! = NLenDest) {return false;} int nDiff = 0; for (int I = 0; I <nLenSource; I ++) {if (strDest. at (I )! = StrSource. at (I) {nDiff ++;} if (1 = nDiff) {return true;} return false;} bool FindNearString (set <string> & setStrFind, map <string, NODE> & mapStrNode, int nDeep) {bool bRet = false; set <string> setStrNext; set <string >:: iterator itSet = setStrFind. begin (); for (; itSet! = SetStrFind. end (); itSet ++) {map <string, NODE >:: iterator it = mapStrNode. begin (); for (; it! = MapStrNode. end (); it ++) {if (-1 = it-> second. nDeep | nDeep = it-> second. nDeep) & IsNear (* itSet, it-> first) {it-> second. nDeep = nDeep; it-> second. vecParentNode. push_back (* itSet); setStrNext. insert (it-> first); if (it-> second. isEnd) {bRet = true ;}}} setStrFind = setStrNext; return bRet;} void OutputArray (string * arrayPath, int nDeep, vector <string> & vecResult) {vector <string> v EcStr; for (int I = nDeep-1; I> = 0; I --) {vecStr. push_back (arrayPath [I]);} vecResult. push_back (vecStr);} void Recur (string * arrayPath, int I, int nDeep, string & strCur, map <string, NODE> & mapStrNode, vector <string> & vecResult) {arrayPath [I] = strCur; map <string, NODE >:: iterator it = mapStrNode. find (strCur); if (it = mapStrNode. end () {OutputArray (arrayPath, nDeep, vecResult); return ;} For (int j = 0; j <(int) mapStrNode [strCur]. vecParentNode. size (); j ++) {I ++; Recur (arrayPath, I, nDeep, mapStrNode [strCur]. vecParentNode [j], mapStrNode, vecResult); I -- ;}} void GetMinPath (string & strBegin, string & strEnd, set <string> & setDict, vector <string> & vecResult) {if (strBegin = strEnd) {return;} map <string, NODE> mapStrNode; setDict. insert (strEnd); set <string >:: iterator it = s EtDict. begin (); for (; it! = SetDict. end (); it ++) {NODE node ={}; node. nDeep =-1; //-1 indicates that the node has not been inserted to the tree. isEnd = (* it = strEnd )? True: false; mapStrNode [* it] = node;} // set the multi-tree <string> setStrFind; setStrFind. insert (strBegin); int nDeep = 1; bool isFind = false; while (setStrFind. size ()! = 0 &&! IsFind) {isFind = FindNearString (setStrFind, mapStrNode, nDeep); nDeep ++;} if (! IsFind) {return;} string * arrayPath = new string [nDeep]; int I = 0; Recur (arrayPath, I, nDeep, strEnd, mapStrNode, vecResult ); delete [] arrayPath;} class Solution {public: vector <string> findLadders (string start, string end, set <string> & dict) {vector <string> vecResult; GetMinPath (start, end, dict, vecResult); return vecResult ;}}; int _ tmain (int argc, _ TCHAR * argv []) {string strBe Gin = "hit"; string strEnd = "cig"; set <string> setDict; setDict. insert ("hot"); setDict. insert ("git"); setDict. insert ("dot"); setDict. insert ("dog"); setDict. insert ("lot"); setDict. insert ("log"); setDict. insert ("cog"); vector <string> vecResult; Solution so; vecResult = so. findLadders (strBegin, strEnd, setDict); vector <string >:: iterator it = vecResult. begin (); for (; it! = VecResult. end (); it ++) {vector <string >:: iterator itStr = it-> begin (); for (; itStr! = It-> end (); itStr ++) {cout <* itStr <"" ;}cout <"\ n" ;}return 0 ;}

Update:

After a special test, it was found that the character string was not taken into account in the dictionary, so the 85 lines of code were:

If (it = mapStrNode. end ())

To:

If (it = mapStrNode. end () | nDeep = I + 1.


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.