24. 两两交换链表中的节点
第一想法:乱七八糟,就不多赘述
以下是代码随想录中给出的python的想法,
- 创建虚拟头结点
- 记录两个变量
- 三步法:(1)1---->3;(2)2---->1;(3)虚拟头结点---->1
- 移动指针
- 返回链表元素
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:
# 创建虚拟头结点
pre = ListNode(next=head)
res = pre
while pre.next and pre.next.next:
# 记录临时节点
cur = pre.next
pos = pre.next.next
# 交换指针 (1)1---->3;(2)2---->1;(3)虚拟头结点---->1
cur.next = pos.next
pos.next = cur
pre.next = pos
# 移动pre
pre = pre.next.next
# 返回虚拟头结点后的链表
return res.next
方法二:代码随想录C++的想法
中间交换指针的三步分别是:
- 头结点---->2;
- 2---->1;
- 1---->3;
class Solution:
def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:
pre = ListNode(next=head)
res = pre
while pre.next and pre.next.next:
# pre指向虚拟头结点,cur指向1,POS指向3
cur = pre.next
pos = pre.next.next.next
# 头结点---->2; 2---->1; 1---->3;
pre.next = cur.next # pre.next=pre.next.next
pre.next.next = cur # pre.next.next = cur
pre.next.next.next = pos
pre = pre.next.next
return res.next
但是讲道理,每个人写代码都会有自己的想法,就像我不知道怎么回事写这个题我的想法就一定要用cur,第一想法就是用cur(指向1,两个节点中前面那个),所以又尽管思路和Carl一样,最后还是写成了如下形式:(最后击败了百分之98,嘿嘿)
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:
pre = ListNode(next=head)
res = pre
while pre.next and pre.next.next:
# pre指向虚拟头结点,cur指向1,POS指向3
cur = pre.next
pos = pre.next.next.next
# 头结点---->2; 2---->1; 1---->3;
pre.next = cur.next # pre.next=pre.next.next
cur.next.next = cur # pre.next.next = cur
cur.next = pos # pre.next.next.next = pos
pre = pre.next.next
return res.next
19. 删除链表的倒数第 N 个结点
第一想法:
- 建立虚拟头结点,因为涉及到删除元素
- 遍历一遍链表,将每个链表的元素添加到列表中,
- 然后第二次遍历列表,查找cur.next=倒数第n个列表元素的值,
- 改变指针,将cur.next = cur.next.nxet
结果:运行超时!
学习代码随想录解法:
解题思想概况
双指针的经典应用,删除倒数第n个节点,让fast移动n步,然后让slow和fast同时移动,直到fast指向链表末尾,删掉slow所指向的节点
具体解题步骤:
- 建立虚拟头结点,并且将slow和fast的初始值设置为虚拟头结点
- fast先走n+1步,只有fast先走n+!步才能让同时移动的slow指向删除节点的上一个节点
- fast和slow同时移动,直到fast指向末尾
- 删除slow指向的下一个节点
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
pre = ListNode(next=head)
slow, fast = pre, pre
while n: # 还有这里,第一次竟然写成了while not n:
fast = fast.next
n -= 1
while fast.next: # 要注意这里是fast.next
slow = slow.next
fast = fast.next
slow.next = slow.next.next
return pre.next
面试题 02.07. 链表相交
根据快慢法则,走的快的一定会追上走得慢的。
在这道题里,有的链表短,他走完了就去走另一条链表,我们可以理解为走的快的指针。那么,只要其中一个链表走完了,就去走另一条链表的路。如果有交点,他们最终一定会在同一个位置相遇
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
curA, curB = headA, headB
while curA != curB:
curA = curA.next if curA else headB
curB = curB.next if curB else headA
return curA
142. 环形链表 II
第一想法:找到有没有环已经很不容易了,还要让我找到环的入口?
学习链接:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def detectCycle(self, head: ListNode) -> ListNode:
slow , fast = head, head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
index_2 = slow
index_1 = head
while index_1 != index_2:
index_1 = index_1.next
index_2 = index_2.next
return index_1
return None