Given a string displaying in the ring format, we can move one character at each step either in clockwise or anticlockwise (or hold still), now we need to retrieve a given string with minimum steps.
Intuition
We can construct a graph from the string and use DFS to search all possible paths, and find the path with minimum steps.
Approach
DFS -> TLE
In the beginning, I am going to use DFS to find all possible paths and find the path with minimum steps.
First, we need construct the graph, each character is adajcent to all other characters in ring
, so there are n=length(ring)
nodes and (n-1)^n
edges. each edge has a weight representing the distance between two characters: weight(i,j)=min(abs(i-j), n - abs(i-j))
(here we use index of the character to represent the node).
Then, we can use DFS to search all possible paths, in each point, we have a state (ring_index, key_index)
, representing the current index on ring
and key
, there are two cases:
ring[ring_index] == key[key_index]
, in this case, we changekey_index
tokey_index+1
and keepsring_index
unchanged (hold still).ring[ring_index] != key[key_index]
, in this case, we need to rotate the stringring
to makering[ring_index] == key[key_index]
, this takes step and notice that there may multiple choices, so we need to go over all of them.
Once key_index == len(key)
, we have found a path and we can now update the result.
The code is given as follows:
|
|
Dynamic programming
The problem of DFS is that, its time complexity grows exponentially if there have multiple repeat characters, which causes TLE (time limit exceeded) error.
So, to reduce the complexity, we can construct the solution from bottom to up. That is, we remember the path to go from the current state, and now we now go one step back, util we back to the original state.
We use dp[i][j]
to represent start from ring[j]
, the minimum rotate steps we need to recover the string key[i...m]
, where m=length(key)
, the target then becomes finding out dp[0][0]
.
Note that we can easily compute dp[m-1][j]
, j=1,\dots,n
, since there is only one character we need to recover, so we start from ring[j]
, and rotate util we find a character ring[k]
such that ring[k]==key[m-1]
, the minimum steps is then updated. The update formula is then given by
$$ dp[i][j] = \min_{k=1,\dots,n,\ ring[k]=key[i]}(dp[i][j],\ dp[i + 1][k] + step(j, k)) $$
where $step(j,k)=\min(|j-k|,\ n-|j-k|)$.
Complexity
Time complexity: The
dp
matrix is of size $m\times n$, and each time, we need to iterate over thering
once. $$O(mn^2)$$Space complexity:The
dp
matrix is of size $m\times n$ $$O(mn)$$
Code
|
|