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!

Asked By: Ashley Liu

||

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
Answered By: typedecker
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.