24. 两两交换链表中的节点
第一次尝试——失败:
class Solution(object):
def swapPairs(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if not head or not head.next:
return head
newHead = head
prev, curr = head, head.next
while prev and curr:
nextNode = curr.next
curr.next = prev
prev.next = nextNode
if prev == head:
newHead = curr
prev, curr = nextNode, nextNode.next
return newHead
失败原因:
- 'NoneType' object has no attribute 'next'——需要调整while范围
- 第二轮交换之后还要将上一轮后一个结点链接到第二轮的第一个结点上 —— 需要fakeHead
第二次尝试——成功:
# 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
"""
if not head or not head.next:
return head
fakeHead = ListNode(next=head)
prev = fakeHead
while prev.next and prev.next.next:
# 标记两个需要交换的结点
curr, post = prev.next, prev.next.next
# 交换位置
curr.next = post.next
post.next = curr
prev.next = post
# 下一个位置
prev = curr
return fakeHead.next
19. 删除链表的倒数第 N 个结点
第一反应解法:两遍遍历,删除对应结点
class Solution(object):
def removeNthFromEnd(self, head, n):
"""
:type head: ListNode
:type n: int
:rtype: ListNode
"""
# 首先获取正数一共多少个结点
curr = head
count = 0
while curr:
count += 1
curr = curr.next
# 判断是否合理的请求
if n > count:
return head
if n == count:
return head.next
# 移到倒数第n+1个结点的地方
t = head
for _ in range(count - n - 1):
t = t.next
if n == 1:
t.next = None
else:
t.next = t.next.next
return head
其他解法:
利用栈:
class Solution(object):
def removeNthFromEnd(self, head, n):
"""
:type head: ListNode
:type n: int
:rtype: ListNode
"""
dummy = ListNode(next = head)
stack = list()
curr = dummy
while curr:
stack.append(curr)
curr = curr.next
for i in range(n):
stack.pop()
prev = stack[-1]
prev.next = prev.next.next
return dummy.next
只遍历一次解法:
最佳解法——快慢指针:
class Solution(object):
def removeNthFromEnd(self, head, n):
"""
:type head: ListNode
:type n: int
:rtype: ListNode
"""
dummyH = ListNode(next = head)
fast, slow = dummyH, dummyH
# fast 先走n+1步
for _ in range(n+1):
fast = fast.next
# fast,slow一起移动
while fast:
slow = slow.next
fast = fast.next
# 删节点
slow.next = slow.next.next
return dummyH.next
面试题 02.07. 链表相交
第一反应解法:利用栈
class Solution(object):
def getIntersectionNode(self, headA, headB):
"""
:type head1, head1: ListNode
:rtype: ListNode
"""
if not headA or not headB:
return None
stackA, stackB = list(), list()
currA, currB = headA, headB
while currA:
stackA.append(currA)
currA = currA.next
while currB:
stackB.append(currB)
currB = currB.next
firstInsertNode = None
while stackA and stackB:
getA = stackA.pop()
getB = stackB.pop()
if getA == getB:
firstInsertNode = getA
else:
break
return firstInsertNode
比较丑陋的解法。所以去学习了一下其他大神的解法。
优雅解法:双指针【参考Krahets的解法】
class Solution(object):
def getIntersectionNode(self, headA, headB):
"""
:type head1, head1: ListNode
:rtype: ListNode
"""
pointerA, pointerB = headA, headB
while pointerA != pointerB:
pointerA = pointerA.next if pointerA else headB
pointerB = pointerB.next if pointerB else headA
return pointerA
142. 环形链表 II
第一反应解法:字典
class Solution(object):
def detectCycle(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if not head:
return None
dic = dict()
curr = head
index = 0
while curr:
if curr in dic.keys():
return curr
dic[curr] = index
curr = curr.next
index += 1
return None
优雅解法: 双指针【参考Krahets的解法】
class Solution(object):
def detectCycle(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
fast, slow = head, head
while True:
if not (fast and fast.next): return
fast, slow = fast.next.next, slow.next
if fast == slow:
break
fast = head
while fast != slow:
fast, slow = fast.next, slow.next
return fast