offer24
- 考虑遍历链表,并在访问各节点时修改
next
引用指向
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
res=None
while head:
# 遍历的每个都要放在前面 2>1>None
tmp=head.next #定位下一个要访问的值
head.next=res#把方向反过来 目的是把上一个res放在末尾 构造1>None
res=head # 暂存(定位)当前的头部指针 1
head=tmp # 往后移
return res
NC40 假设链表中每一个节点的值都在 0 - 9 之间,那么链表整体就可以代表一个整数给定两个这种链表,请生成代表两个整数相加值的结果链表。
从后往前对齐,跟我们整数再做加法一样
def f(head):
'''把节点放入列表中,并反转'''
res= []
while head:
res.append(head)
head = head.next
return res[::-1]
class Solution:
def addInList(self , head1: ListNode, head2: ListNode) -> ListNode:
l1,l2=f(head1), f(head2)
pre=0#上一个的进位数
if len(l1) < len(l2):#保证l1长
l1, l2 = l2, l1
for i in range(len(l1)):
if i<len(l2) or pre:
tmp=(l1[i].val+l2[i].val)+pre if i<len(l2) else l1[i].val+pre
pre=tmp//10
l1[i].val=tmp%10#用11保存相加后的一位数
else:#l2加完了 有没有进位 不用往下进行
break
if pre:#不要忘记剩的一个进位数
c=ListNode(pre)
c.next=l1[-1]
return c
return l1[-1]
NC21 将一个节点数为 size 链表 m 位置到 n 位置之间的区间反转
#遍历到m的位置 采用头插法,依次遍历将链表逆序 O(n) O(1)
class Solution:
def reverseBetween(self , head: ListNode, m: int, n: int) -> ListNode:
Test=ListNode(-1) #定义哨兵节点,老套路了
Test.next=head
pre,cur,i = Test,Test.next,0
for i in range(m-1):#前面照常遍历
pre = cur
cur = cur.next
for j in range(n-m):#第m个开始反转,反转n-m次
tmp = cur.next#3 4
cur.next =tmp.next#2》4 2》5
tmp.next =pre.next#3》2 4》3
pre.next =tmp#1》3 1》4
#12345 13245 14325
return Test.next
NC50 题:将给出的链表中的节点每 k 个一组翻转,返回翻转后的链表。如果链表中的节点数不是 k 的倍数,将最后剩下的节点保持原样。
# 将链表分成k组反转,首先遍历一遍链表求取链表长度i
# 判断链表长度i是否大于k值,若大于将这组值进行反转
# 将i值减去k得到剩余i值,继续判断剩余i的长度是否大于等于k,若大于重复2,否则直接返回链表
class Solution:
def reverseKGroup(self , head: ListNode, k: int) -> ListNode:
Test=ListNode(-1) #定义哨兵节点,老套路了
Test.next=head
pre,cur,i,lend=Test,Test.next,0,Test.next
while lend:
i=i+1 #求链表总长度
lend=lend.next
while head and i>=k: #分组进行判断,一组组进行反转
for j in range(k-1): #当前这组满足反转的
print(cur.val)
tmp = cur.next
cur.next = tmp.next
tmp.next = pre.next
pre.next = tmp
i = i-k #分组的思想,减去已经反转的个数,供下一次循环得到条件
pre = cur
cur = pre.next
return Test.next