Order in Python for loop (LeetCode 219 Contains Duplicate II)
Question:
https://goodtecher.com/leetcode-219-contains-duplicate-ii/
In this Python solution, why does visited[nums[i]] = i
have to come after the if condition? I don’t understand why the code wouldn’t work if the order is reversed like this:
visited = {}
for i in range(len(nums)):
visited[nums[i]] = i
if nums[i] in visited and abs(i - visited[nums[i]]) <= k:
return True
return False
I would appreciate an explanation as well as some sources to help me understand what I don’t understand about how order works in Python loops. Thank you!
Answers:
Problem presented -:
The code presented above in the OP, after thorough investigation seems to be in an attempt to solve a problem wherein, the code returns true
if there exists two distinct indices i
and j
in a list of numbers nums
, such that -:
nums[i] == nums[j]
abs(i - j) <= k
Also, the constraints stated in the link provided are -:
1 <= nums.length <= 10^5
-10^9 <= nums[i] <= 10^9
0 <= k <= 10^5
[k is thus given to always be positive for any given testcase]
Explanation of the solution -:
Now, the code given as a solution tries to solve this problem, by declaring a dictionary visited
, and looping using a for loop from 0 to the length of the given list of numbers[nums
]. Every iteration of the loop it considers the loop variable i
to be the index i
as stated in the problem, and tries to fetch the value of the key nums[i]
and use that as the index j
, given that nums[i]
is already a key in visited, since one of the problem’s condition is to check for nums[i] == nums[j]
, and thus -:
if nums[i] in visited and abs(i - visited[nums[i]]) <= k:
Structure of the visited dictionary as pseudo code -:
{nums[k] : k}
or {value_at_some_index_k : index_k}
Also, Incase the value for nums[i]
, does not already exist as a key in the visited
dictionary, it adds it to the dictionary as a key, but in such a case the if statement is not invoked, since it precedes the assignment. This also answers the question posed, which is that why exactly is there a need for the if statement to precede the assignment, in the loop order.
visited[nums[i]] = i
The reason assigning before the if statement does not work -:
Note that the above statement, only acts as a way to register this value as a key for the loop’s future iterations(if any), to check for a match.
If the assignment was to precede the if statement, then the if statement would’ve always returned true[given that k >= 0], since -:
i = 0, 1, 2...
j = visited[nums[i]]
, and visited[nums[i]] = i
, due to assignment so, j = i
abs(i - j) = abs(i - i) = abs(0) = 0
and k >= 0
is given.
Also here is a simpler version of the same code, to make it feel more relatable -:
visited = {} # declare the visited dict, format -: {nums[k] : k} for some index k
for i in range(len(nums)): # loop with i as loop variable over the range of indexes for nums
if nums[i] in visited :
# since visited[nums[i]] is the value of the key and is equal to j,
# that means the key must be nums[j], so nums[i] == nums[j] is already satisfied.
j = visited[nums[i]] # Assigning this to j, to make it more easier to related with the problem.
if abs(i - j) <= k: # check for the condition demanded in the problem.
return True # return true if the conditions are met.
visited[nums[i]] = i # Incase the value doesn't already exist, add it to the dict.
continue # continue the loop
return False
https://goodtecher.com/leetcode-219-contains-duplicate-ii/
In this Python solution, why does visited[nums[i]] = i
have to come after the if condition? I don’t understand why the code wouldn’t work if the order is reversed like this:
visited = {}
for i in range(len(nums)):
visited[nums[i]] = i
if nums[i] in visited and abs(i - visited[nums[i]]) <= k:
return True
return False
I would appreciate an explanation as well as some sources to help me understand what I don’t understand about how order works in Python loops. Thank you!
Problem presented -:
The code presented above in the OP, after thorough investigation seems to be in an attempt to solve a problem wherein, the code returns true
if there exists two distinct indices i
and j
in a list of numbers nums
, such that -:
nums[i] == nums[j]
abs(i - j) <= k
Also, the constraints stated in the link provided are -:
1 <= nums.length <= 10^5
-10^9 <= nums[i] <= 10^9
0 <= k <= 10^5
[k is thus given to always be positive for any given testcase]
Explanation of the solution -:
Now, the code given as a solution tries to solve this problem, by declaring a dictionary visited
, and looping using a for loop from 0 to the length of the given list of numbers[nums
]. Every iteration of the loop it considers the loop variable i
to be the index i
as stated in the problem, and tries to fetch the value of the key nums[i]
and use that as the index j
, given that nums[i]
is already a key in visited, since one of the problem’s condition is to check for nums[i] == nums[j]
, and thus -:
if nums[i] in visited and abs(i - visited[nums[i]]) <= k:
Structure of the visited dictionary as pseudo code -:
{nums[k] : k}
or {value_at_some_index_k : index_k}
Also, Incase the value for nums[i]
, does not already exist as a key in the visited
dictionary, it adds it to the dictionary as a key, but in such a case the if statement is not invoked, since it precedes the assignment. This also answers the question posed, which is that why exactly is there a need for the if statement to precede the assignment, in the loop order.
visited[nums[i]] = i
The reason assigning before the if statement does not work -:
Note that the above statement, only acts as a way to register this value as a key for the loop’s future iterations(if any), to check for a match.
If the assignment was to precede the if statement, then the if statement would’ve always returned true[given that k >= 0], since -:
i = 0, 1, 2...
j = visited[nums[i]]
, andvisited[nums[i]] = i
, due to assignment so,j = i
abs(i - j) = abs(i - i) = abs(0) = 0
andk >= 0
is given.
Also here is a simpler version of the same code, to make it feel more relatable -:
visited = {} # declare the visited dict, format -: {nums[k] : k} for some index k
for i in range(len(nums)): # loop with i as loop variable over the range of indexes for nums
if nums[i] in visited :
# since visited[nums[i]] is the value of the key and is equal to j,
# that means the key must be nums[j], so nums[i] == nums[j] is already satisfied.
j = visited[nums[i]] # Assigning this to j, to make it more easier to related with the problem.
if abs(i - j) <= k: # check for the condition demanded in the problem.
return True # return true if the conditions are met.
visited[nums[i]] = i # Incase the value doesn't already exist, add it to the dict.
continue # continue the loop
return False