24.两两交换链表中的节点
有点开心的这道题,手动写出了一道中等难度的题目,自信心+1
两个技巧:第一个是使用了两个虚拟头节点,省去发现头节点的分情况讨论步骤
第二个是使用tmp变量去保存临时节点
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
cålass Solution(object):
def swapPairs(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
vir1 = ListNode()
vir2 = ListNode()
vir1.next = vir2
vir2.next = head
a = vir1
b = vir2
while True :
tmp = b.next
b.next = a
if tmp == None or tmp.next == None :
a.next = tmp
break
a.next = tmp.next
a = tmp
b = tmp.next
return vir1.next
下面来看一下随想录是怎么做的吧
这里面使用的迭代逻辑显然更复杂,current这个变量代表当前index,
一切思路源于这个current index.交换的是这个节点next和next.next。每一次迭代只是一个变量往后走。这很大程度上缓解了index溢出的压力,很巧妙但是很难想。
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution(object):
def swapPairs(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
# 创建一个虚拟头节点
vir = ListNode()
vir.next = head
pre = vir
while pre.next != None and pre.next.next != None:
# 记录临时变量
cur = pre.next
post = pre.next.next
#开始交换节点
cur.next = post.next
post.next = cur
pre.next = post
pre = pre.next.next
return vir.next
19.删除链表的倒数第N个节点
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution(object):
def removeNthFromEnd(self, head, n):
"""
:type head: ListNode
:type n: int
:rtype: ListNode
"""
num =0
vir = ListNode(next = head)
cur = vir
while cur.next :
num+=1
cur = cur.next
index = num - n + 1
cur = vir
while index >1 :
cur = cur.next
index -= 1
cur.next = cur.next.next
return vir.next
使用一趟:
用个list存起来就好了
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution(object):
def removeNthFromEnd(self, head, n):
"""
:type head: ListNode
:type n: int
:rtype: ListNode
"""
memory =[]
num =0
vir = ListNode(next = head)
cur = vir
while cur.next :
num+=1
memory.append(cur)
cur = cur.next
index = num - n + 1
memory[index-1].next = memory[index-1].next.next
return vir.next
面试题 02.07. 链表相交
使用一个list记录一个列表中的list node就好了啊
另一个list遍历的时候再check里面 list 是否包含遍历到的节点
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def getIntersectionNode(self, headA, headB):
"""
:type head1, head1: ListNode
:rtype: ListNode
"""
list1 = []
cur = headA
while cur:
list1.append(cur)
cur = cur.next
cur = headB
while cur:
if cur in list1:
return cur
cur = cur.next
return None
142.环形链表II
o(n) 空间解决这个问题很简单。
有没有环形就是一个node的入度是大于1的就可以,把检测到node的次数当作入度的度用list存起来就可以检测出来啦。
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def detectCycle(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
memory = []
cur = head
while cur :
if cur in memory:
return cur
else:
memory.append(cur)
cur = cur.next
return None
使用o(1)的空间方案解决这个问题:
可以尝试使用双指针嘛,固定一个指针指向的节点。然后另一个指针向后滑动不会相遇就更新前面的指针。