好久没有刷题了,之前都是使用C++刷题的,现在发现Python用的多,并且对于Python的语法掌握的并不熟练,所以逼着自己通过刷题掌握Python,所以后期的刷题全都使用Python语言,语言是次要的。 下面的题目:
链表交换相邻元素
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例:
给定 1->2->3->4, 你应该返回 2->1->4->3.
思路一:三指针遍历循环
这其实是一种思想,三指针很重要,等刷完了链表这里的题目之后,集中总结一下。 这种思想的思路是这样:
首先,先判断head,如果只有一个节点或者一个都没有,那么就直接返回,无需交换。
如果上面不成立,则先建立一个头结点,然后一个尾指针始终指向交换之后的尾部。 然后建立三个指针: pre,p,q。pre在最前面,p中间,q是后面。 如果p不是空的时候, q指向p后面的节点,防止丢掉。 然后把前面的两个交换,交换完毕之后,把指针归位。
class Solution:
def swapPairs(self, head: ListNode) -> ListNode:
if not head or not head.next:
return head
# 声明一个头结点好算
headnode = ListNode(-1)
headnode.next = head
rear = headnode
# 三个指针
pre = head
p = pre.next
while p:
q = p.next
p.next = pre
pre.next = q
rear.next = p
rear = pre
pre = q
p = pre.next if pre else None
return headnode.next
这种代码,最好根据代码,手动画一下,只需要画出第一步即可。
并且还有一点要注意,如果pre=None的时候,后面是不可能出现.next,所以上面有了这样的一个判断。
思路二:递归
递归相对来说比较简单了,还是先判断,如果只有一个或者一个节点都没有,那么就返回head,不用交换
如果不是,那么如果给了我后面的两个交换完的结果之后,我前面的两个再交换一下即可,所以可以使用递归。并且借助Python的元组赋值特性,代码可以更简洁。
class Solution:
def swapPairs(self, head: ListNode) -> ListNode:
if not head and not head.next:
return head
else:
head, head.next, head.next.next = head.next, head, self.swapPairs(head.next.next)
return head
思路三: 双指针遍历,然后交换数值
这个题目中说了不单单交换数值,如果没限制的话,可以通过交换内部节点的值解决这个题,那样会更加简单,这里只是提供另一种思路:
指定p和q两个指针遍历, 如果p和q都不为空,那么就交换两个的值,然后都往后走。
class Solution:
def swapPairs(self, head: ListNode) -> ListNode:
if not head:
return
prev = head
rear = prev.next
while rear:
prev.val, rear.val = rear.val, prev.val
prev = rear.next
rear = prev.next if prev else None
return head
这里依然要注意,是不是循环里面是不是有变量已经成为了None,一定要警惕这一点,否则会报错。
总结
这个题的思路还是比较清晰,只不过初步换成Python,有点不太习惯,尤其是一些方式上,但是Python可以更加简洁的解决问题。 后面都改成Python代码, 如果不太明白Python的元组解包赋值,可以看一下这篇博客:
Python连续赋值需要注意的地方