标签:介绍 影响 反转 实现 lis and 计算 str elf
线性表(三)——线性表(六)这四节笔者介绍了链表的实现及变形,本节将简单介绍几种链表的应用。
问题来源:
力扣:206. 反转链表
问题简述:
给定一个链表,请将这个链表反转。
问题分析:
在顺序表中,我们常采用的反转手段是根据索引交换列表的前半段和后半段实现反转。但链表的存储方式不同于顺序存储,那么我们该如何做呢?
一般而言,方法主要有两种:
Python实现:
# 迭代式
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
if not head:
return
pre = None
cur = head
while cur:
tmp = cur.next
cur.next = pre
pre = cur
cur = tmp
return pre
# 递归式
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
if not head or not head.next:
return head
nextNode = self.reverseList(head.next)
head.next.next = head
head.next = None
return nextNode
问题来源:
力扣:2. 两数相加
问题简述:
将两个数分别逆序存储在两个链表中,请以链表的形式返回这两个数的和。
问题分析:
实现这一操作并不难,但有几个细节需要注意:
Python实现:
class Solution:
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
res = ListNode(0)
cur = res # 游标
carry = 0 # 进位数
while l1 or l2 or carry:
residual1 = l1.val if l1 else 0
residual2 = l2.val if l2 else 0
cur.next = ListNode((residual1+residual2+carry) % 10)
carry = (residual1 + residual2 + carry) // 10
l1 = l1.next if l1 else None
l2 = l2.next if l2 else None
cur = cur.next
return res.next
问题来源:
力扣:142. 环形链表
问题简述:
给定一个链表,判断是否存在环,若存在,找出环起点。
问题简述:
笔者在第一次碰到这个问题的时候想法是直接使用哈希表记录经过的结点,第一次碰到的重复的结点一定是环起点,但这样做的坏处是无法在O(1)空间下解决这一问题。
仔细思考,我们会发现通过快慢指针可以优化空间,利用快慢指针可以迅速判环,如果存在换且快慢指针第一次相遇,通过数学推导会发现此时慢指针与环起点的距离同链表起点与环起点的距离“相同”,因此再设置第三个指针与慢指针同向移动即可到达环起点。
Python实现:
class Solution:
def detectCycle(self, head: ListNode) -> ListNode:
# 判环
cur1, cur2 = head, head
while cur2 and cur2.next:
cur1 = cur1.next
cur2 = cur2.next.next
if cur1 == cur2:
break
if cur2 is None or cur2.next is None:
return
# 快指针走的路是慢指针的两倍,它们走的非环路相同,且慢指针在绕环第一圈必定与快指针相遇
# 设非环路为s,环起点至相遇点为x,相遇点至环起点为y,快指针绕圈数为n
# 公式2*(s+x) = s + x + n*(x+y) ==> s = y + (n-1)*(x+y)
# 推导公式后一部分为环的整数倍,因此不影响计算,可以得知当第一次相遇时慢指针距离环口s步
# 设置一个新指针指向链表起点,与慢指针同向同速移动,移动y + (n-1)*(x+y)步必定相遇于环口
# 寻找环起点
cur3 = head
while cur3 != cur1:
cur1 = cur1.next
cur3 = cur3.next
return cur1
标签:介绍 影响 反转 实现 lis and 计算 str elf
原文地址:https://www.cnblogs.com/yiwen-statistics/p/13804048.html