其他分享
首页 > 其他分享> > 反转链表系列题

反转链表系列题

作者:互联网

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(N)O(N),空间复杂度O(1)O(1)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)O(N),空间复杂度O(N)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表示,
在这里插入图片描述
经过交换后,现在的节点顺序如下:

在这里插入图片描述
可见,23对应的节点已经交换了顺序,接下来更新pPrevpNode的值即可继续后续的翻转。

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)O(N),空间复杂度O(N)O(N)O(N)。

3. 反转链表的第m个至第n个节点

在这里插入图片描述

4. K个一组反转链表

在这里插入图片描述

标签:head,系列,反转,pPrev,next,链表,pNode,节点,pNext
来源: https://blog.csdn.net/shahuzi/article/details/97139196