LeetCode-Reverse Linked List I & II
两个链表反转问题。
206. Reverse Linked List
Reverse a singly linked list.
Hint:
A linked list can be reversed either iteratively or recursively. Could you implement both?
Solution
iteratively
# 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
"""
rev = None
while head:
head.next,rev,head = rev,head,head.next
return rev
recursively
# 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
"""
return self.reverse_recursively(head, None)
def reverse_recursively(self, head, new_head):
if not head:
return new_head
nxt = head.next
head.next = new_head
return self.reverse_recursively(nxt, head)
92. Reverse Linked List II
Reverse a linked list from position m to n. Do it in-place and in one-pass.
For example:
Given 1->2->3->4->5->NULL
, m = 2 and n = 4,
return 1->4->3->2->5->NULL
.
Solution
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def reverseBetween(self, head, m, n):
"""
:type head: ListNode
:type m: int
:type n: int
:rtype: ListNode
"""
if not head:
return None
dummy = ListNode(None)
dummy.next = head
pre = dummy
for i in range(m-1):
pre = pre.next
start = pre.next
then = start.next
for i in range(n-m): # n到m之间有n-m+1个节点,需要反转n-m次
# 每次不断的把then节点反转到pre节点的后面,然后then节点后移一个,直到反转完毕
start.next = then.next
then.next = pre.next
pre.next = then
then = start.next
return dummy.next
更加直观的解法:
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def reverseBetween(self, head, m, n):
"""
:type head: ListNode
:type m: int
:type n: int
:rtype: ListNode
"""
dummy = ListNode(None)
dummy.next = head
whead = head # 窗口开始位置
wtail = head # 窗口结束位置
ohead = dummy # 窗口的前一个位置
for i in range(n-m): # 初始化窗口长度
wtail = wtail.next
for i in range(m-1): # 移动窗口到位置m
ohead, whead, wtail = whead, whead.next, wtail.next
otail = wtail.next # 窗口结束的后一个位置
wtail.next = None
revhead, revtail = self.reverse(whead) # 反转窗口内部链表
ohead.next, revtail.next = revhead, otail # 将反转后的窗口与未反转部分连接起来
return dummy.next
def reverse(self, head): # 反转链表
pre = None
cur = tail = head
while cur:
cur.next, pre, cur = pre, cur, cur.next
return pre, tail