反转一个单链表。
示例:
输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL
进阶:
你可以迭代或递归地反转链表。你能否用两种方法解决这道题?
迭代法:
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def reverseList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
reversedHead = None
currNode = head
prevNode = None
while currNode != None:
nextNode = currNode.next
currNode.next = prevNode
prevNode = currNode
currNode = nextNode
reversedHead = prevNode
return reversedHead
使用迭代的方法较为直观,且空间复杂度比递归法低,O(n)->O(1)。该方法需要使用到两个指针,prevNode表示前驱节点,currNode表示现在指向的节点。每次循环时,先通过currNode的next指针获取下一个节点,随后将currNode指向前一个前驱节点prevNode,最后更新currNode以及prevNode。
循环结束的条件为遍历到空节点,此时链表的入口就是prevNode(prevNode为原链表的最后一个节点)。
递归法:
class Solution(object):
def reverseList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if head == None or head.next == None:
return head
reversedHead = self.reverseList(head.next)
head.next.next = head
head.next = None
return reversedHead
相比于迭代法,递归法代码看上去更加简洁明了,但是理解起来更为费劲。在思考递归问题时我们要从上到下思考:
- 子问题是什么
- base case是什么
- 在当前层需要做什么
子问题:除去当前节点,翻转剩余的链表,例如除去1,reverseList(2->3->4->5),递归的结果应该为 5->4->3->2
base case:当前节点为空,返回空,当前节点的下一个节点为空,返回当前该节点。
在当前层需要做什么:改变当前节点在链表中的位置。 即把1插到5->4->3->2的后面。由于原来1.next = 2,而我们在当前层只有头节点5的指针,所以节点2可以直接通过节点1的next找到,把1.next.next设为1就是把节点2指向该节点1。