160. 相交链表
- 编写一个程序,找到两个单链表相交的起始节点。
思路:双指针方式
- 将a和b两个链表串联起来,将b链表的尾巴指向a节点的头部,将a节点的尾巴指向b链表的头部。
- 定义两个指针,一个从a链表头出发,一个从b链表头出发,因为是环形的,最终两个链表会相遇,而相遇的节点就是相交的节点。
代码实现:
class Solution(object):
def getIntersectionNode(self, headA, headB):
a,b = headA,headB
# 定义了两个节点a和b,只要a和b不等就继续遍历
while a!=b:
# 这步很关键,请对照动态图配合理解
# 当a的下一个为空时,就a就从b链表头开始遍历
a = a.next if a else headB
# 同理,b也是类似的
b = b.next if b else headA
return a
21. 合并两个有序链表
- 将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
思路:
- 首先注意特殊情况,(1)链表L1为空,(2)链表L2为空,(3)L1和L2都为空。使用三目表达式判断。
- L1和L2两个链表可能一样长,也可能不一样长。一样长时,链表合并完成,L1和L2都为空,不一样长时,只有L1和L2中的某一个为空,此时只需要将合并后的链表尾巴指向那个不为空的L1或者L2。
代码实现:
class Solution:
def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
# 处理特殊情况
if not (l1 and l2):
return l1 if l1 else l2
#增加一个冗余的节点,方便后续处理
p = ListNode(-1)
head = p
while l1 and l2:
# 如果l1的值小于等于l2的值,就将p指向l1
if l1.val <= l2.val:
p.next = l1
l1 = l1.next
else:
p.next = l2
l2 = l2.next
p = p.next
# 如果l1不为空就将p.next指向l2,如果l1为空就指向l2,如果l2也为空那就指向空
p.next = l1 if l1 else l2
return head.next
24. 两两交换链表中的节点
- 给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例:
给定 1->2->3->4, 你应该返回 2->1->4->3.
思路:三指针方式
- 定义三个指针,一个作为过渡指针,两个作为交换指针。
- 交换完成时,过渡指针向前走两步,交换指针根据过渡指针的位置重新放置,进行交换。
代码实现
def swapPairs(self, head: ListNode) -> ListNode:
if not (head and head.next):
return head
# 增加空头节点,便于处理前两个节点的交换
h = ListNode(-1)
h.next = head
t = h
while t.next and t.next.next:
# a, b指针根据过渡指针的位置放置
a = t.next
b = t.next.next
# 进行交换
t.next = b
a.next = b.next
b.next = a
# 过渡指针向后移动两个节点
t = t.next.next
return h.next
声明
部分图片及思路来自:
作者:wang_ni_ma
链接:https://leetcode-cn.com/problems/intersection-of-two-linked-lists/solution/dong-hua-yan-shi-160-xiang-jiao-lian-biao-by-user7/