class Solution {
public:
vector<int> executeInstructions(int n, vector<int>& startPos, string s) {
// Say we have:
// 0 1 2 3 4 5
// R R D D L U
// For now, say we only care about horizontal movement:
// 0 1 2 3 4 5
// R R - - L -
// Say indexesOfXs is {2 : {0, 4}}, {3 : {1}}.
// That means that given that we start at position 1. Once we
// leave index 0, we'll be at position 2. Once we leave index 1,
// we'll be at position 3. Once we leave index 4, we'll be at
// position 2.
// The indexes we must leave in order to be at position 2
// are {0, 4}. The indexes we must leave to be at position
// 3 are {1}.
unordered_map<int, deque<int>> indexesOfYs{};
unordered_map<int, deque<int>> indexesOfXs{};
int xVal = startPos[1];
int yVal = startPos[0];
for(int ii=0; ii<s.size(); ++ii)
{
if (s[ii] == 'R')
{
++xVal;
indexesOfXs[xVal].push_back(ii);
}
else if (s[ii] == 'L')
{
--xVal;
indexesOfXs[xVal].push_back(ii);
}
else if (s[ii] == 'U')
{
--yVal;
indexesOfYs[yVal].push_back(ii);
}
else // 'D'
{
++yVal;
indexesOfYs[yVal].push_back(ii);
}
}
vector<int> ans(s.size(), 0);
// At the start zero steps are removed, we start at index 0.
int exSteps = 0;
// If the position is -1 or n, then we have stepped off the grid.
int yLookForMax = n;
int yLookForMin = -1;
int xLookForMax = n;
int xLookForMin = -1;
// ii is the index in s. We lose the left most letter after each iteration.
// The positions reached in indexesOfXs and indexesOfYs assume we are going through each
// of the indices in s, but at the end of the iteration the left most letter is deleted.
// Say the left most letter is an R. Then instead of correcting all the values in indexesOfXs,
// update xLookForMax from n to (n + 1).
for(int ii=0; ii<s.size(); ++ii)
{
// For each direction find the smallest index for sought position.
int smallestIndex = s.size();
if (indexesOfYs.find(yLookForMax) != indexesOfYs.end())
{
while( (!indexesOfYs[yLookForMax].empty()) && (indexesOfYs[yLookForMax].front() < exSteps))
{
indexesOfYs[yLookForMax].pop_front();
}
if (indexesOfYs[yLookForMax].empty())
{
indexesOfYs.erase(yLookForMax);
}
else
{
smallestIndex = std::min(smallestIndex, indexesOfYs[yLookForMax].front());
}
}
if (indexesOfYs.find(yLookForMin) != indexesOfYs.end())
{
while(!indexesOfYs[yLookForMin].empty() && (indexesOfYs[yLookForMin].front() < exSteps))
{
indexesOfYs[yLookForMin].pop_front();
}
if (indexesOfYs[yLookForMin].empty())
{
indexesOfYs.erase(yLookForMin);
}
else
{
smallestIndex = std::min(smallestIndex, indexesOfYs[yLookForMin].front());
}
}
if (indexesOfXs.find(xLookForMax) != indexesOfXs.end())
{
while(!indexesOfXs[xLookForMax].empty() && (indexesOfXs[xLookForMax].front() < exSteps))
{
indexesOfXs[xLookForMax].pop_front();
}
if (indexesOfXs[xLookForMax].empty())
{
indexesOfXs.erase(xLookForMax);
}
else
{
smallestIndex = std::min(smallestIndex, indexesOfXs[xLookForMax].front());
}
}
if (indexesOfXs.find(xLookForMin) != indexesOfXs.end())
{
while(!indexesOfXs[xLookForMin].empty() && (indexesOfXs[xLookForMin].front() < exSteps))
{
indexesOfXs[xLookForMin].pop_front();
}
if (indexesOfXs[xLookForMin].empty())
{
indexesOfXs.erase(xLookForMin);
}
else
{
smallestIndex = std::min(smallestIndex, indexesOfXs[xLookForMin].front());
}
}
ans[ii] = smallestIndex - exSteps;
++exSteps;
if (s[ii] == 'R')
{
++xLookForMin;
++xLookForMax;
}
else if (s[ii] == 'L')
{
--xLookForMin;
--xLookForMax;
}
else if (s[ii] == 'U')
{
--yLookForMin;
--yLookForMax;
}
else // 'D'
{
++yLookForMin;
++yLookForMax;
}
}
return ans;
}
};