反转链表系列题
作者:互联网
1.反转链表
反转链表有两种做法:迭代法和递归法,这里两种都写一下
1.1 迭代法
定义三个指针pPrev
,pNode
,pNext
,分别指向当前节点的前一节点
、当前节点
、当前节点的后一节点
,只要当前节点不为空,就不断地将当前节点的next
指向前一节点,然后更新当前节点为下一节点,最后返回pPrev
,因为退出条件为当前节点为空节点,故此时pPrev
为最后一个节点。(PS:这个代码的前后相连真的是美)
def reverseLinkedListIter(head):
pPrev = None
pNode = head
while pNode != None:
pNext = pNode.next
pNode.next = pPrev
pPrev = pNode
pNode = pNext
return pPrev
时间复杂度O(N),空间复杂度O(1)。
1.2 递归法
递归法的思想是,每次翻转当前节点后面的链表,然后把下一节点的next
指向当前节点,直接看代码。
def reverseLinkedListRecursion(head):
if head == None or head.next == None:
return head
newHead = reverseLinkedListRecursion(head.next)
head.next.next = head
head.next = None
return newHead
这个代码的巧妙之处在于newHead
一直没变,是最后一个节点。
时间复杂度O(N),空间复杂度O(N)。
2.成对反转链表
题目描述:
乍一看这个题目,我有一种很粗暴的解法,就是把链表按单双数分解成两个链表,然后再重新合并,这种方法肯定是行得通的,此处讲另外两种方法,也分别是迭代法和递归法。
2.1 迭代法
思路也是定义三个指针
def reversePairIter(head):
# 定义一个虚拟节点,方便处理
dummy = ListNode(0)
pPrev = dummy
pNode = head
while pNode != None and pNode.next != None:
pNext = pNode.next
pNode.next = pNext.next
pNext.next = pNode
pPrev.next = pNext
pPrev = pNode
pNode = pNode.next
return dummy.next
下面用一张图来说明一下上面代码的第8~10行的过程,注意,这里1,2,3,4
表示的是原先的顺序,其中pPrev
是已经翻转过的,上面三个步骤分别用图中的带圈1,2,3
表示,
经过交换后,现在的节点顺序如下:
可见,2
和3
对应的节点已经交换了顺序,接下来更新pPrev
和pNode
的值即可继续后续的翻转。
2.2 递归法
思路是定义三个指针,分别指向当前节点、下一节点和下下节点,首先将下一节点的next
指向当前节点,然后将当前节点的next
指向下下节点翻转后的返回值(递归),最后返回下一节点(此时下一节点变为头节点)。
def reversePairRecursion(head):
if head == None or head.next == None:
return head
pNext = head.next
pNextNext = pNext.next
pNext.next = head
head.next = reversePairRecursion(pNextNext)
return pNext
时间复杂度O(N),空间复杂度O(N)。
3. 反转链表的第m个至第n个节点
4. K个一组反转链表
标签:head,系列,反转,pPrev,next,链表,pNode,节点,pNext 来源: https://blog.csdn.net/shahuzi/article/details/97139196