思路,设定一个虚拟头节点防止原始的头节点被删了需要讨论,其他很简单
简单复习一下节点的定义
python
class ListNode:
def __init__(self, val, next):
self.next = next
self.val = val
python
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
dummy = ListNode()
dummy.next = head
node = dummy
while node.next is not None:
if node.next.val == val:
node.next = node.next.next
else:
node = node.next
return dummy.next
思路:怎么搞了个链表长度来orz
思路也比较清晰,难度不是很大,基本功的题目
python
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class MyLinkedList:
def __init__(self):
self.dummy = ListNode()
self.size = 0
def get(self, index: int) -> int:
if index < 0 or index >= self.size:
return -1
node = self.dummy.next
for i in range(index):
node = node.next
return node.val
def addAtHead(self, val: int) -> None:
self.dummy.next = ListNode(val, self.dummy.next)
self.size += 1
def addAtTail(self, val: int) -> None:
node = self.dummy
while node.next:
node = node.next
node.next = ListNode(val)
self.size += 1
def addAtIndex(self, index: int, val: int) -> None:
if index < 0 or index > self.size:
return
node = self.dummy
for i in range(index):
node = node.next
node.next = ListNode(val, node.next)
self.size += 1
def deleteAtIndex(self, index: int) -> None:
if index < 0 or index >= self.size:
return
node = self.dummy
for i in range(index):
node = node.next
node.next = node.next.next
self.size -= 1
# Your MyLinkedList object will be instantiated and called as such:
# obj = MyLinkedList()
# param_1 = obj.get(index)
# obj.addAtHead(val)
# obj.addAtTail(val)
# obj.addAtIndex(index,val)
# obj.deleteAtIndex(index)

思路,考虑当前节点和上一个节点cur 和 pre:初始指向头节点和空节点,向后顺延,在cur不为空时,用temp标注cur的下一个节点,先让cur指向pre,再让pre换到cur的位置,cur换到temp的位置即可
python
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
cur, pre = head, None
while cur:
temp = cur.next
cur.next = pre
pre = cur
cur = temp
return pre

思路:设定一个虚拟节点指向head.next,便于后面返回,针对每一次情况,设定pre为当前节点的上一个,cur为当前节点
采用思路:想用递归的方法试一试,当交换完前两个节点之后,即再次对后面两个节点进行处理,也可以理解为对一个失去了前两个节点的新链表进行处理,合理引入递归。
考虑递归的操作,pre节点指向第一个,cur节点指向第二个:全部交换之后期待1节点指向4节点,也即指向交换后的第二组cur,2节点期待指向1节点,也即再递归新的链表。头节点为cur.next:
python
pre.next = self.swapPairs(cur.next)
cur.next - pre
整体代码如下:
python
class Solution:
def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:
if head is None or head.next is None:
return head
pre = head
cur = head.next
pre.next = self.swapPairs(cur.next)
cur.next = pre
return cur

思路:设定一个虚拟节点指向头节点,node放在虚拟节点上,node取到下一个时,n-=1,如果node为空则直接返回虚拟节点的next,当n=1则执行删除,让该节点直接指向next的next即可
上面的思路不对,是倒数第n个节点
正确思路:让一个节点先走n步,然后再让两个节点从不同起始点出发,到达终点时,慢节点也到达了要删的节点前面,就很显然了。
python
class Solution:
def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
dummy = ListNode(val = 1)
dummy.next = head
node1 = dummy
while n != 0:
node1 = node1.next
n -= 1
node2 = dummy
while node1.next is not None:
node1 = node1.next
node2 = node2.next
node2.next = node2.next.next
return dummy.next
再考虑一下递归:也即不断地获取节点的相对位置。给定一个虚拟节点指向头节点,从虚拟节点向后一直遍历到最后一个节点后面。也即第0个节点,此时递归函数返回0,让count = DFS(node.next)+ 1,需要获取dfs函数的值时就继续带入,直到获得0,依次返回,直到找到count等于n+1时,此时让该节点指向下下个即可
python
class Solution:
def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
dummy = ListNode(0,head)
def DFS(node):
if node is None:
return 0
count = DFS(node.next)+1
if count == n+1:
node.next = node.next.next
return count
DFS(dummy)
return dummy.next

思路:考虑到将两个链表和并,如果二者有交点,一定会交会。停止条件是二者相等,此时遇见了或者都到达空节点。返回任意一节点即可。数学思想
python
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
nodea,nodeb = headA,headB
while nodea != nodeb:
nodea = nodea.next if nodea is not None else headB
nodeb = nodeb.next if nodeb is not None else headA
return nodea

思路:数学问题:快慢指针,慢指针走一个快指针走两个,如有环一定相遇,如无环快指针会滞空,所以让判定条件是快指针以及快指针的下一个节点不空。获得交点后,考虑从交点出发比从起点出发都走了k步,于是再走一次,会在入口点相遇
python
class Solution:
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
slow,fast = head,head
while fast is not None and fast.next is not None:
slow = slow.next
fast = fast.next.next
if slow == fast:
flag = slow
slow = head
while slow != flag:
slow = slow.next
flag = flag.next
return flag
return None