链表是一种数据结构,可以通过链表的指针,得到所属的值和next的指针。
Leetcode2,Leetcode445 关于链表的两数相加.
''' 给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。 请你将两个数相加,并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外,这两个数都不会以 0 开头。 输入:l1 = [2,4,3], l2 = [5,6,4] 输出:[7,0,8] 解释:342 + 465 = 807. 输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9] 输出:[8,9,9,9,0,0,0,1] '''
class Solution:
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
result = ListNode(0)
val = l1.val+l2.val
# 判断是否大于10
cur_add = 1 if val >= 10 else 0
result.val = val % 10 if val >= 10 else val
pre = result
while (l1 is not None) or (l2 is not None):
l1 = l1.next if l1 else None
l2 = l2.next if l2 else None
if l1 or l2:
cur = ListNode(0)
# 补全链表 如果链表为空
l1_val = l1.val if l1 else 0
l2_val = l2.val if l2 else 0
# 计算当前链表的值并且判断是否大于10
val = cur_add + l1_val + l2_val
cur_add = 1 if val >= 10 else 0
cur.val = val % 10 if val >= 10 else val
# 将当前节点连接到result.next
pre.next = cur
pre = cur
else:
break
if cur_add:
pre.next = ListNode(1,None)
return result
Leetcode445 不是逆序的,所以要将链表旋转。就变成逆序相加。再把结果旋转回去。
旋转链表是Leetcode206.
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 输入:head = [1,2,3,4,5] 输出:[5,4,3,2,1] 输入:head = [1,2] 输出:[2,1] 输入:head = [] 输出:[]
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
pre = None
cur = head
while cur:
# 记录当前节点的下一个节点
tmp = cur.next
# 然后将当前节点指向pre
cur.next = pre
# pre,cur和 cur,tmp交换
pre, cur = cur, tmp
return pre
旋转链表还可以旋转部分链表。
class Solution:
def reverseBetween(self, head: ListNode, left: int, right: int) -> ListNode:
# 放置一个哑节点,指向head
dummy_node = ListNode(-1)
dummy_node.next = head
pre = dummy_node
# 在left之前的节点都不需要翻转
for _ in range(left - 1):
pre = pre.next
# current 是 pre的下一个节点
cur = pre.next
for _ in range(right - left):
# next的节点 实际要前移
next = cur.next
# next.next 指向 current.next,current 往后移动
cur.next = next.next
# next.next 指向 pre.next,next往前移动
next.next = pre.next
# pre.next 指向 next,相当于吧current后面一个往前。
pre.next = next
return dummy_node.next
分链表。给定left和right,反转left和right中间。
除了单向链表,还有环形链表。
环形链表如何判断:主要通过快慢指针。
class Solution:
def hasCycle(self, head: ListNode) -> bool:
if (head == None) or (head.next == None): return False
slow = head
fast = head
# 当快慢指针同步的时候. 证明有环
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
return True
return False
以及如何判断环的初始节点位置,需要通过快慢指针,两次相遇即可。
class Solution:
def detectCycle(self, head: ListNode) -> ListNode:
if (head is None) or (head.next is None): return
slow = head
fast = head
while True:
if not (fast and fast.next): return
fast = fast.next.next
slow = slow.next
if fast == slow: break
fast = head
while fast != slow:
fast = fast.next
slow = slow.next
return fast
以及判断环的长度,从第一次相遇到第二次相遇,慢指针比快指针少走一圈。
class Solution:
def CycleLen(self, head: ListNode) -> ListNode:
if (head is None) or (head.next is None): return
ct = 0
slow = head
fast = head
while True:
if not (fast and fast.next): return ct
fast = fast.next.next
slow = slow.next
if fast == slow: break
ct = 1
fast = fast.next.next
slow = slow.next
while fast != slow:
fast = fast.next.next
slow = slow.next
ct += 1
return ct
以及移除链表重复元素:
class Solution:
def removeDuplicateNodes(self, head: ListNode) -> ListNode:
pre = ListNode(-1)
pre.next = head
cur = head
# 记载节点
nodes = set()
while cur:
if cur.val not in nodes:
nodes.add(cur.val)
pre, cur = pre.next, cur.next
else:
cur = cur.next
pre.next = cur.next
return head