1. 指定区间反转链表(left-right)
这里有两个思路:
第一个是直接在链表上进行反转,确定好需要反转的区间里面的第一个元素(cur)和反转区间前的那个元素(pre)后,不停的把cur后面那个元素放到pre后面,循环right-left次,即可实现反转。
第二个是将原来的链表进行拆分,反转区间前的那一段,需要反转的那一段,反转区间后面的那一段(请注意,记的把前两段最后一个元素的next指向None来切断链表);接着用上一篇文章里的反转链表把需要反转的那部分反转;最后处理完把这三部分再拼接起来,实现链表指定区间的反转。
2. 两两交换链表元素
实现原理为找到pre节点 (从新设置的dummy开始),对pre.next和pre.next.next进行反转操作,之后推进pre节点。相关代码实现如下:
另外,在代码实现过程中出现了下面的错误,在此总结原因 :我把cur放到了循环外层导致了一些问题,假设我在反转1,2,3,4,5,在完成了第一次循环后我的cur为2,但是原链表变成了2,1,3,4,5, 导致2的下一个元素又变成了1 而不是我希望的3,因此陷入了死循环,右图为改正过后的代码。
---->
3. 链表加一
要实现链表加一有两种方法:
第一种不需要反转链表, 思路是先遍历链表找到最右边的那个非9的数字,然后把它加一,之后把它后面的数字归零(因为满9进1),要注意处理一下边界情况(999),代码和解释如下:
第二种是先反转链表,然后从左往右遍历,如果是9就变0,然后进入下一位,直到不是9的时候,下一位加一,注意边界情况(999).
def plusOne2(self, head):
def reverse(head):
dummy = ListNode(-1)
cur = head
while cur:
next = cur.next
cur.next = dummy.next
dummy.next = cur
cur = next
return dummy.next
head = reverse(head)
curr = head
while curr and curr.val == 9:
curr.val = 0
curr = curr.next
if curr:
curr.val += 1
ans = reverse(head)
return ans
else:
head = ListNode(1, head)
return head
3. 链表相加
链表相加相当于是链表加一的进阶版,实现链表相加也有两种方法
第一种是使用栈,把链表的数据append到列表中,然后依次pop出来,进行相加(注意:这里还需要引入一个参数来代表是否有进1,如下面代码中的carry)
第二种使用链表反转,反转后按位依次相加计算,最后再把得到的结果反转回来。
def reverseList(self, head):
prev = None
curr = head
while curr:
nextTemp = curr.next
curr.next = prev
prev = curr
curr = nextTemp
return prev
def addTwoNumbersI(self, l1, l2):
ans = ListNode(0, None)
DUMMY_HEAD, res = ans, 0
p1, p2 = l1, l2
while p1 != None or p2 != None or res == 1:
ans.next = ListNode(0, None)
ans = ans.next
if p1 != None and p2 != None:
sums = p1.val + p2.val
if sums + res < 10:
ans.val = sums + res
res = 0
else:
ans.val = sums + res - 10
res = 1
p1, p2 = p1.next, p2.next
elif p1 == None and p2 != None:
sums = p2.val
if sums + res < 10:
ans.val = sums + res
res = 0
else:
ans.val = sums + res - 10
res = 1
p2 = p2.next
elif p2 == None and p1 != None:
sums = p1.val
if sums + res < 10:
ans.val = sums + res
res = 0
else:
ans.val = sums + res - 10
res = 1
p1 = p1.next
else:
ans.val = res
res = 0
return DUMMY_HEAD.next
# 调用入口
def addTwoNumbers2(self, l1, l2):
return self.reverseList(self.addTwoNumbersI(self.reverseList(l1), self.reverseList(l2)))
4. 回文序列(1,2,3,2,1)
在学完链表反转之后可以使用 快慢指针法 (准确找到中间点然后切段)+ 链表反转法(把后半段反转),实现从头开始比较两端链表。