【链表】
203. 移除链表元素
# 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 removeElements(self, head, val):
"""
:type head: ListNode
:type val: int
:rtype: ListNode
"""
head0 = ListNode()
head0.next = head # 虚拟节点负责维护包含head的链表
head1 = head0 # head1 负责每次判断条件,调整指针
while head1.next:
if head1.next.val == val:
head1.next =head1.next.next
else:
head1 = head1.next
print(head0)
print(head1)
return head0.next
备注: 要设置虚拟节点,维护一个新的链表 以及 控制指针指向的变量
707. 设计链表
class ListNode(object):
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class MyLinkedList(object):
def __init__(self):
self.head0 = ListNode()
self.len = 0
def get(self, index):
"""
:type index: int
:rtype: int
"""
if index < 0 or index >= self.len:
return -1
head1 = self.head0
i = 0
while i < index:
head1 = head1.next
i += 1
return head1.next.val
def addAtHead(self, val):
"""
:type val: int
:rtype: None
"""
newhead = ListNode(val)
newhead.next = self.head0.next
self.head0.next = newhead
self.len += 1
def addAtTail(self, val):
"""
:type val: int
:rtype: None
"""
newtail = ListNode(val)
head1 = self.head0
while head1.next :
head1 = head1.next
head1.next = newtail
self.len += 1
def addAtIndex(self, index, val):
"""
:type index: int
:type val: int
:rtype: None
"""
newindex = ListNode(val)
head1 = self.head0
i = 0
if index >= 0 and index <= self.len:
while i < index:
head1 = head1.next
i += 1
newindex.next = head1.next
head1.next = newindex
self.len += 1
def deleteAtIndex(self, index):
"""
:type index: int
:rtype: None
"""
head1 = self.head0
i = 0
if index >= 0 and index < self.len:
while i < index:
head1 = head1.next
i += 1
head1.next = head1.next.next
self.len -= 1
206. 翻转链表
# 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 reverseList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
head0 = None
head1 = head
while head1:
temp = head1.next
head1.next = head0
head0 = head1
head1 = temp
return head0
备注: 这题用的是双指针,但是要定义一个中间变量来保存head1.next的值
24. 两两交换链表中的节点
# 方法一:双指针法
# 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
"""
head0 = ListNode(0)
head0.next = head
head1 = head0
while head1:
if head1.next == None or head1.next.next == None:
break
temp = head1.next
head1.next = head1.next.next
temp.next = head1.next.next
head1.next.next = temp
head1 = head1.next.next
return head0.next
# 方法二:构造栈
class Solution(object):
def swapPairs(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
stack = []
head0 = ListNode(0)
head1 = head0
while head :
if head.next == None :
break
stack.append(head)
stack.append(head.next)
head = head.next.next
head1.next = stack.pop()
head1.next.next = stack.pop()
head1 = head1.next.next
head1.next = head
return head0.next
19. 删除链表的第n个节点
19. # 构造栈
# 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
"""
stack = []
NewTail = None
while head:
stack.append(head)
head = head.next
for i in range(len(stack)):
res = stack.pop()
if i+1 == n:
continue
res.next = NewTail
NewTail = res
return NewTail
链表相交
# 也是构造栈
# 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
"""
StackA, StackB = [], []
while headA:
StackA.append(headA)
headA = headA.next
while headB:
StackB.append(headB)
headB = headB.next
MinLen = min(len(StackA), len(StackB))
res = None
for i in range(MinLen):
if StackA[-1] == StackB[-1]:
res = StackA.pop()
res = StackB.pop()
return res
142. 环形链表II
# 方法一 列表法(类似于构造栈)
class Solution(object):
def detectCycle(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
Circle = []
head0 = head
while head0:
if head0.next in Circle:
return head0.next
Circle.append(head0)
head0 = head0.next
return None
# 方法二 数学推导
class Solution(object):
def detectCycle(self, head):
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
链表总结:
1、可以看到一般用两个方法,一个是双指针,但是需要注意下标变化和指针的移动情况,比较万能,没有额外的空间复杂度; 第二个是列表法,也相当于构造一个栈,我一般把需要找到链表中某个节点的题目都用列表法做,就是空间复杂度会高,但是可以利用栈的特性很快找到想要的节点。