24. 两两交换链表中的节点
题意
两两交换链表中的结点
解题思路
递归
找终止条件:本题终止条件很明显,当递归到链表为空或者链表只剩一个元素的时候,没得交换了,自然就终止了。
找返回值:回给上一层递归的值应该是已经交换完成后的子链表。
单次的过程:因为递归是重复做一样的事情,所以从宏观上考虑,只用考虑某一步是怎么完成的。我们假设待交换的俩节点分别为head和next,next的应该接受上一级返回的子链表(参考第2步),就相当于是一个含三个节点的链表交换前两个节点。
维护奇数、偶数链表列表
分别维护奇数和偶数的列表,并且进行交换,在最后如果没有交换完的话,补充即可;
迭代
两两进行交换,交换完成后指向下一对的起始位置,继续两两交换,直到没有下一对为止;
实现
分别对应以上三种方法的实现;
class Solution(object):
def swapPairs(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if not head or not head.next:
return head
next = head.next
# 假定该函数返回的是已经交换完成的
head.next = self.swapPairs(next.next)
next.next = head
return next
def swapPairs2(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if not head or not head.next:
return head
tmp = head
index = 0
# 奇数、偶数链表节点列表
node_list1, node_list2 = [], []
while tmp:
if index % 2:
node_list1.append(tmp)
else:
node_list2.append(tmp)
tmp = tmp.next
index += 1
root = ListNode(0)
tmp = root
i, j = 0, 0
len1, len2 = len(node_list1), len(node_list2)
while i < len1 and j < len2:
if (i + j) % 2 == 0:
tmp.next = node_list1[i]
i += 1
else:
tmp.next = node_list2[j]
j += 1
tmp = tmp.next
if i != len1:
for p in range(i, len1):
tmp.next = node_list1[p]
tmp = tmp.next
if j != len2:
for p in range(j, len2):
tmp.next = node_list2[p]
tmp = tmp.next
tmp.next = None
return root.next
def swapPairs3(self, head):
if not head or not head.next:
return head
right_head = head.next
# 下面均是会发生变化的变量
tmp_head = head
next_node = head.next
while next_node:
# 两两交换
next_next_node = next_node.next
next_node.next = tmp_head
tmp_head.next = None
if not next_next_node:
return right_head
# 交换完后指向正确的下一对
tmp_head.next = next_next_node.next if next_next_node.next else next_next_node
# 更新当前位置
tmp_head = next_next_node
next_node = next_next_node.next
return right_head