数据结构-链表
2.剑指 Offer 24. 反转链表-简单
剑指 Offer 24. 反转链表
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
- python 递归方法:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
# 递归思路
# 终止条件
curHead = head
if not curHead or not curHead.next:
return curHead
cur = self.reverseList(curHead.next)
# 这里不可以用curHead.next = curHead, curHead是返回的结果, 可能是很长的结果, cur仅仅是头节点;
curHead.next.next = curHead
curHead.next = None
return cur
- python迭代方法:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
if not head:
return None
pHead = head
pTmp1 = head
# 下面两条顺序不能变化,否则就会报错;
pHead = pHead.next
pTmp1.next = None
while pHead:
# 原则: 两前1后指针
pTmp2 = pHead.next
pHead.next = pTmp1
pTmp1 = pHead
pHead = pTmp2
return pTmp1
206. 反转链表-简单
- python迭代实现
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
# 迭代思路:
if not head:
return []
preHead = head
curHead = head.next
preHead.next = None
tmpHead = preHead
while curHead:
tmpHead = curHead.next
curHead.next = preHead
preHead = curHead
curHead = tmpHead
return preHead
- 迭代实现
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
# 递归思路
# 终止条件
curHead = head
if not curHead or not curHead.next:
return curHead
cur = self.reverseList(curHead.next)
# 这里不可以用curHead.next = curHead, curHead是返回的结果, 可能是很长的结果, cur仅仅是头节点;
curHead.next.next = curHead
curHead.next = None
return cur
3.leetcode-25. K 个一组翻转链表
25. K 个一组翻转链表难度困难639收藏分享切换为英文关注反馈给你一个链表,
每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
示例:
给你这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5
思路: 使用 递归的思路:
递归思维:k 个一组反转链表
python实现:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
# 翻转区间[a, b) 的元素, 注意是 左闭右开。
def reverse(a, b):
pre = ListNode()
cur = a
nxt = a
# while终止条件变成 != b
while cur != b:
nxt = cur.next
cur.next = pre
pre = cur
cur = nxt
# 反转后的头节点
return pre
if not head:
return None
a = b = head
for i in range(k):
if not b:
return head
b = b.next
# 返回z反转后的头节点
newHead = reverse(a, b)
# a: 反转之前的头节点, 然后把 反转后的 下一次的头节点拼起来
a.next = self.reverseKGroup(b, k)
return newHead
148. 排序链表
⭐Sort List (归并排序链表)
方法一:链表归并排序(递归思路)
- python实现:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def sortList(self, head: ListNode) -> ListNode:
# 思路: 先进性递归切分,然后再进行merge
if not head or not head.next:
return head
slowPointer, fastPoiter = head, head.next
while fastPoiter and fastPoiter.next:
slowPointer = slowPointer.next
fastPoiter = fastPoiter.next.next
# save and cut
mid = slowPointer.next
slowPointer.next = None
left, right = self.sortList(head), self.sortList(mid)
return self.merge(left, right)
# 两个有序链表合并操作;
def merge(self, left, right):
dummy = res = ListNode(0)
while left and right:
if left.val < right.val:
dummy.next = left
left = left.next
else:
dummy.next = right
right = right.next
dummy = dummy.next
dummy.next = left if left else right
return res.next
方法二:链表归并排序(从底至顶直接合并)
- python实现
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def sortList(self, head: ListNode) -> ListNode:
#
curNode, length = head, 0
# 计算链表长度
while curNode:
curNode = curNode.next
length += 1
# dummy节点
res = ListNode(0)
res.next = head
# merge the list in different intv
intv = 1
while intv <= length:
# pre:
# h:
preNode = res
curHead = res.next
while curHead:
# get the merge head 'h1'、'h2'
mergeHead1, mergeLength = curHead, intv
# 获得mergeHead1
while curHead and mergeLength:
curHead = curHead.next
mergeLength -= 1
if mergeLength:
break # no need to merge because the h2 is None
# 获得mergeHead2
mergeHead2, mergeLength = curHead, intv
while mergeLength and curHead:
curHead = curHead.next
mergeLength -= 1
mergeLength1, mergeLength2 = intv, intv - mergeLength
# merge the mergeHead1 and mergeHead2
while mergeLength1 and mergeLength2:
if mergeHead1.val < mergeHead2.val:
preNode.next = mergeHead1
mergeHead1 = mergeHead1.next
mergeLength1 -= 1
else:
preNode.next = mergeHead2
mergeHead2 = mergeHead2.next
mergeLength2 -= 1
preNode = preNode.next
preNode.next = mergeHead1 if mergeLength1 else mergeHead2
# 进一步: preNode走完,走扫 curNode之前;
while mergeLength1 > 0 or mergeLength2 > 0:
preNode = preNode.next
mergeLength1 -= 1
mergeLength2 -= 1
preNode.next = curHead
intv = 2*intv
return res.next