This is the code which I ran.
int minimumCardPickup(vector<int>& cards) {
int N = cards.size();
int l = 0, r = 0, res = INT_MAX;
unordered_map<int, int> pos;
while (r < N) {
if (pos.find(cards[r]) != pos.end()) {
l = pos[cards[r]];
res = min(res, r - l 1);
}
pos[cards[r]] = r ; //Here
}
return res == INT_MAX ? -1 : res;
}
let's take an example: cards = [1, 2, 3, 2, 4] The line with the comment should update the map to the following after 3 iterations:
pos = {[1, 0], [2, 1], [3, 2]}
But instead it updates the map like this:
pos = {[2, 0], [3, 1]}
It should have done something like this: get value of cards[r]
and then assign pos[cards[r]]
with the value of r
and then do r
for next iteration but instead, it did r
then get value of cards[r]
and then assign pos[cards[r]]
with value of r
before increment.
If I do this, it works fine.
pos[cards[r]] = r;
r ;
Can someone explain why it works like that?
CodePudding user response:
As you correctly identified, the problem is here:
pos[cards[r]] = r ; //Here
In earlier standards:
If you post-increment or post-decrement a variable, you should not read the value of it again before a sequence point (in this case, ;
). This is because post-increment might occur any time during the statement (as long as the expression evaluates to the old value).
From C 17, for any operation l = r
, the evaluation of r
is sequenced-before the evaluation of l
(including side effects), so it’s a valid expression, but still not what’s expected in the code. Either do the post-increment on the left-hand side of the =
(thereby restricting to c 17 and newer), or simply do the increment as a distinct statement (as you correctly specified).