本系列文章是我刷代码随想录过程中的笔记。代码地址:leetcode
今天是我刷“代码随想录”的第四天
今日内容
-
- 两两交换链表中的节点
- 19.删除链表的倒数第N个节点
- 面试题 02.07. 链表相交
- 142.环形链表II
leetcode 24. 两两交换链表中的节点
这道题使用虚头节点。过程如下
- 首先定义一个头节点0,此时链表尾0 -> 1 -> 2 -> 3
- 记录下1,2,3等3个节点的地址
- 将2的地址赋给0的下一个,同时前进一步,目前在2。此时链表为0 -> 2 -> 3,1
- 将1的地址赋给2的下一个,同时前进一步,目前在1,此时链表为 0 -> 2 -> 1,3
- 将3的地址赋给1的下一个,此时链表为 0 -> 2 -> 1 -> 3。可以看到,已经完成了交换。 循环上述步骤即可。注意到,因为有三个节点,因此需要保证 node,node.next,node.next.next均不为空。
下面是求解代码
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]:
root = ListNode(-1,head)
node = root
while node and node.next and node.next.next:
# 1
nxt = node.next
# 2
nnxt = nxt.next
# 3
nnnxt = nnxt.next
# -> 2
node.next = nnxt
node = node.next
# -> 1
node.next = nxt
node = node.next
# -> 3
node.next = nnnxt
return root.next
leetcode 19.删除链表的倒数第N个节点
这道题可以采用双指针法。先让快的跳n步,然后快慢同时跳直到快指针为空。此时,慢指针的下一个恰好为要删除的节点。 直接删除就行。
class Solution:
def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
head_dummy = ListNode()
head_dummy.next = head
slow, fast = head_dummy, head_dummy
while(n!=0): #fast先往前走n步
fast = fast.next
n -= 1
while(fast.next!=None):
slow = slow.next
fast = fast.next
#fast 走到结尾后,slow的下一个节点为倒数第N个节点
slow.next = slow.next.next #删除
return head_dummy.next
或者,也可以先记录链表长度,找到待删除元素的正数序号,然后再进行删除。代码如下
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]:
num = 0
tmp = head
while tmp:
tmp = tmp.next
num += 1
index = num - n
root = ListNode(-1, head)
node = root
for _ in range(index):
node = node.next
node.next = node.next.next
return root.next
leetcode 面试题 02.07. 链表相交
定义a,b两个指针,开始跳。如果a == b,说明啊a是相交点或者a为空。
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
if not headA or not headB:
return None
a = headA
b = headB
while a != b:
a = a.next if a else headB
b = b.next if b else headA
return a
142. 环形链表 II - 力扣(Leetcode)
这道题需要找出环形链表的入口节点。因此在判断有环后,需要从头开始跳,找到入口。
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
class Solution:
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
slow, fast = head, head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
# 如果相遇
if slow == fast:
p = head
q = slow
while p != q:
p = p.next
q = q.next
# 你也可以return q
return p
return None
总结
链表部分的基础题结束了。有些题还是值得多做几遍的。