I was solving a question on leetcode. "41. First Missing Positive"
For swapping, when I used
nums[i],nums[nums[i]-1] = nums[nums[i]-1],nums[i]
I got TLE (time limit exceeded).
But
nums[nums[i]-1],nums[i] = nums[i],nums[nums[i]-1]
is working perfectly.
This is not just the case with leetcode.
I tried to understand the difference, spent 1 hour on the problem. And then reached out to Google bard and Chatgpt. Both struggled.
After spending lots of time, I got an answer "Given that both codes share the same logic and conditional statements, it remains puzzling why Code 1 is exhibiting an issue, especially in the scenario you described with the infinite loop."
Here is my code:
class Solution:
def firstMissingPositive(self, nums: List[int]) -> int:
i,n = 0,len(nums)
while i<n:
if nums[i]>0 and nums[i]<=n and nums[nums[i]-1]!=nums[i]:
#nums[i],nums[nums[i]-1] = nums[nums[i]-1],nums[i]
nums[nums[i]-1],nums[i] = nums[i],nums[nums[i]-1]
else:
i+=1
for i in range(n):
if nums[i]!=i+1:
return i+1
return n+1
The commented out statement is giving TLE , but second one is working fine. Can someone please explain, what is causing this? Is a,b=b,a
and b,a=a,b
different?
I also defined the function in Python IDLE, added a print statement below the swapping statement, and it got stuck in infinite loop again.
Yes, the order in which the assignment happens changes.
In the first case,
nums[i],nums[nums[i]-1] = nums[nums[i]-1],nums[i]
First, nums[i]
gets updated, then, nums[num[i] -1]
gets updated, so that second assignment target is affected by the first change.
So it is equivalent to something like:
temp = nums[nums[i]-1],nums[i]
nums[i] = temp[0]
nums[nums[i]-1] = temp[1]
In the second case,
temp = nums[i], nums[nums[i]-1]
nums[nums[i]-1] = temp[0]
nums[i] = temp[1]
First nums[nums[i]-1]
gets updated, then nums[i]
gets updated. The nums[i]
inside nums[nums[i]-1]
will be different than the first case.
So, if you look at the documentation for assignment statements they give a simple example of what is going on:
Although the definition of assignment implies that overlaps between the left-hand side and the right-hand side are ‘simultaneous’ (for example
a, b = b, a
swaps two variables), overlaps within the collection of assigned-to variables occur left-to-right, sometimes resulting in confusion. For instance, the following program prints[0, 2]
:
x = [0, 1]
i = 0
i, x[i] = 1, 2 # i is updated, then x[i] is updated
print(x)