This question is basically two-fold:
- How do you solve the actual problem? and
- How do you generally read in graph data?
The first question is a bit narrow, and it sounds like the second one is of more interest to you in the long run. So, let me just point you to flow algorithms. It's a step up from Dijkstra in terms of implementation complexity, but as you already realized, there is just so much you can do with a single path. Network flows are a whole different thing.
As for reading your input, it dramatically depends on the kind of graph library you want to use. A few years ago, when I was active in these competitions, we weren't allowed to use 3rd-party libraries, so had to roll our own implementations.
In that case, you have to think ahead if you want to read in a complete matrix, or if you want to keep the graph as an adjacency list. These are the two most important data structures to know for graph algorithms. (more precisely, often you don't need to think ahead, because the problem input specification directs you to one or the other)
Reading input for an adjacency matrix is as straightforward as two nested for-loops. In the body of the inner loop, you simply read one value and assign it to one matrix cell. Done.
For adjacency lists you need to prepare the list of neighbors of a node for each of the nodes, i.e. for n
nodes you prepare a list of size n
that contains an empty list for each entry. Then you again have two nested for-loops: the outer loop goes over the nodes, the inner loop reads the neighbors of that node and adds them to the corresponding inner list. Voila - an adjacency list representation of the graph.
Important addition for programming challenges/competitions: Make sure that you know in your dreams how to write both variants before you even think about competing. There are limitless sample questions and practice sites out there. Search around for problems with graph input, then write and rewrite the input code again and again. It should almost always be nearly the same code, and once you've grown accustomed to it, reading in input like the one you gave above takes you 5 minutes at most. If you want to compete with the really strong players in that field, you should be able to code the input reading for this within about 1 minute or less.
I had to look up the Damerau-Levenshtein distance on wikipedia, so forgive me if this is wrong. But it looks like it only allows for transposing adjacent letters and not any arbitrary ones. So your example "abcdef" -> "abcfad" with transpose of d and f doesn't work. It seems to me you have modified the definition of the algorithm and are no longer calculating the Damerau-Levenshtein distance.
Best Answer
I would simulate in the most generic way as follows: This is what I believe the low-level machine would do.
You can define Frame as follows:
Now you can wonder why there is only one push into the stack even though you have 2 recursive calls. It is because The first recursive call is pushed into the stack with a frame having different
state
andsharedData
compared to the frame pushed into the stack by the second call.Since you said, you only want approach and hint. I hope this is enough. The details is done in the method
doWork()
. ThereFrame
's instances variables are changed.I took me a while to come up with this. Hopefully, there is nothing wrong here.