0

Question: Swap Two Nodes in Linked List

Answer 1:

def swapNodes(self, head, v1, v2):
        dummyHead = ListNode(-1, head)
        pre_v1 = None
        pre_v2 = None
        curNode = dummyHead
        while curNode.next:
            if curNode.next.val == v1:
                pre_v1 = curNode
            elif curNode.next.val == v2:
                pre_v2 = curNode

            if pre_v1 and pre_v2:

                pre_v1.next, pre_v2.next, pre_v1.next.next, pre_v2.next.next = \
                pre_v2.next, pre_v1.next, pre_v2.next.next, pre_v1.next.next
                break

            curNode = curNode.next
        return dummyHead.next

This answer lead to a wrong answer when the input is 1->2->3->4->null. The output should be 1->4->3->2->null. But it returns 1->4->null

If I change

pre_v1.next, pre_v2.next, pre_v1.next.next, pre_v2.next.next = \
pre_v2.next, pre_v1.next, pre_v2.next.next, pre_v1.next.next

to

pre_v1.next, pre_v2.next = pre_v2.next, pre_v1.next
pre_v1.next.next, pre_v2.next.next = pre_v2.next.next, pre_v1.next.next

The answer is correct.

Do I miss something? Is there any "trap" that I have to be careful about when swapping values in this way?

Munichong
  • 3,861
  • 14
  • 48
  • 69
  • 1
    Possible duplicate of [Multiple assignment and evaluation order in Python](http://stackoverflow.com/questions/8725673/multiple-assignment-and-evaluation-order-in-python) – Moinuddin Quadri Nov 22 '16 at 18:00
  • As Moinuddin said, the first one evaluates in a different order: The order is important: the order you swap `pre_v1.next` & `pre_v1.next.next` will affect the outcome – TemporalWolf Nov 22 '16 at 18:01

1 Answers1

0

The thing you have to understand with using the tuple-unpacking trick to swap values in Python is that they essentially all happen in parallel, not sequentially. In your first example, for instance, pre_v1.next.next takes on the value of pre_v2.next_next, but in the same expression you also change pre_v1.next, so once the whole thing is done evaluating, pre_v1.next.next won't point where you think it does because you're now essentially evaluating (pre_v2.next).next, which has also been changed.

user3030010
  • 1,767
  • 14
  • 19