No need to have inner and outer ifs: both of them do essentially the same.
Instead, we can check if the indices are different when the numbers at i and j are the same.
def find_duplicate(nums):
i = 0
while i < len(nums):
j = nums[i] - 1
if nums[i] != nums[j]:
nums[i], nums[j] = nums[j], nums[i] # swap
else:
if i != j:
return nums[i] # we have found the duplicate
i += 1
return -1