A linked list is a linear data structure consisting of a series of nodes, where each node contains data and a pointer to the next node (in a singly linked list) or both pointers to the next node and the previous node (in a doubly linked list). The nodes in a linked list can be stored non-contiguously in memory, which is different from an array where elements are stored contiguously in memory.
Singly Linked List Node:
class Node:
def __init__(self, data=None):
self.data = data
self.next = None
Doubly Linked List Node:
class DoubleNode:
def __init__(self, data=None):
self.data = data
self.prev = None
self.next = None
The linked list is a very important data structure. In many cases, it provides more flexible operations and storage methods than arrays, especially in scenarios where elements need to be inserted and deleted frequently. However, its disadvantage in random access to elements also means it may not be the best choice when frequent element access is required, and an appropriate data structure should be selected based on specific application scenarios.
For the remaining types of problems, please refer to my channel.
everecursion-CSDN博客everecursion关注python,github,chatgpt领域.https://blog.csdn.net/gcsyymm?type=blog
Linked List Cyclehttps://leetcode.cn/problems/linked-list-cycle/https://leetcode.cn/problems/linked-list-cycle/Diff:EZ
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def hasCycle(self, head: Optional[ListNode]) -> bool:
fast = slow = head
while fast and fast.next:
fast = fast.next.next
slow = slow.next
if fast == slow:
return True
return False
Add Two Numbershttps://leetcode.cn/problems/add-two-numbers/https://leetcode.cn/problems/add-two-numbers/Diff: MED
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def addTwoNumbers(
self, l1: Optional[ListNode], l2: Optional[ListNode]
) -> Optional[ListNode]:
cur = dummy = ListNode(0)
carry = 0
while l1 or l2 or carry:
val1 = l1.val if l1 else 0
val2 = l2.val if l2 else 0
cur.next = ListNode((val1 + val2 + carry) % 10)
carry = (val1 + val2 + carry) // 10
cur = cur.next
l1 = l1.next if l1 else None
l2 = l2.next if l2 else None
return dummy.next
Merge Two Sorted Listshttps://leetcode.cn/problems/merge-two-sorted-lists/Diff: EZ
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def mergeTwoLists(
self, list1: Optional[ListNode], list2: Optional[ListNode]
) -> Optional[ListNode]:
dummy = cur = ListNode(0)
while list1 or list2:
if not list1 or not list2:
if not list1:
cur.next = list2
break
if not list2:
cur.next = list1
break
else:
if list1.val < list2.val:
cur.next = ListNode(list1.val)
list1 = list1.next
cur = cur.next
else:
cur.next = ListNode(list2.val)
list2 = list2.next
cur = cur.next
return dummy.next
Copy List with Random Pointerhttps://leetcode.cn/problems/copy-list-with-random-pointer/Diff: MED
"""
# Definition for a Node.
class Node:
def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None):
self.val = int(x)
self.next = next
self.random = random
"""
class Solution:
def copyRandomList(self, head: "Optional[Node]") -> "Optional[Node]":
if not head:
return head
# create the copied node right interleaved with the current node
cur = head
while cur:
cur.next = Node(cur.val, cur.next)
cur = cur.next.next
# assign the random pointer for the copied nodes
cur = head
while cur:
if cur.random:
cur.next.random = cur.random.next
cur = cur.next.next
# split the copied nodes from the original nodes list
cur = head
new_head = cur.next
# PAY ATTENTION TO THE CONDITION FOR THE WHILE LOOP
# cur represent original node; tmp represent copied node
while cur.next.next:
tmp = cur.next
cur.next = tmp.next
tmp.next = cur.next.next
cur = cur.next
return new_head
Reverse Linked List IIhttps://leetcode.cn/problems/reverse-linked-list-ii/Diff: MED
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverseBetween(
self, head: Optional[ListNode], left: int, right: int
) -> Optional[ListNode]:
p0 = dummy = ListNode(next=head)
for _ in range(left - 1):
p0 = p0.next
pre = None
cur = p0.next
for _ in range(right - left + 1):
suc = cur.next
cur.next = pre
pre = cur
cur = suc
# p0.next was pointing to None
# p0.next was the ending node of reversed list
p0.next.next = cur
# p0 was the node before the reverse operation
p0.next = pre
return dummy.next
Reverse Nodes in k-Grouphttps://leetcode.cn/problems/reverse-nodes-in-k-group/
Diff: HARD
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverseKGroup(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:
cnt = 0
cur = head
while cur:
cur = cur.next
cnt += 1
dummy = p0 = ListNode(next=head)
cur, pre = head, None
while cnt >= k:
cnt -= k
for _ in range(k):
suc = cur.next
cur.next = pre
pre = cur
cur = suc
tmp = p0.next
tmp.next = cur
p0.next = pre
p0 = tmp
return dummy.next
Remove Nth Node From End of Listhttps://leetcode.cn/problems/remove-nth-node-from-end-of-list/Diff: MED
# Definition for singly-linked list.
# 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]:
# two pointers with step diff of n;
# instant know left is the last n th node; when the right reach the end
left = right = dummy = ListNode(next=head)
# let right moving n steps ahead
for _ in range(n):
right = right.next
while right.next:
left = left.next
right = right.next
# when right reach the end; we know left is the last n th node
left.next = left.next.next
return dummy.next
Remove Duplicates from Sorted List IIhttps://leetcode.cn/problems/remove-duplicates-from-sorted-list-ii/Diff: MED
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]:
cur = dummy = ListNode(next=head)
while cur.next and cur.next.next:
val = cur.next.val
if cur.next.next.val == val:
while cur.next and cur.next.val == val:
cur.next = cur.next.next
else:
cur = cur.next
return dummy.next
Rotate Listhttps://leetcode.cn/problems/rotate-list/Diff: MED
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def rotateRight(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:
if not head:
return
cur = head
count = 1
while cur.next:
count += 1
cur = cur.next
cur.next = head
k %= count
for _ in range(count - k):
cur = cur.next
newHead = cur.next
cur.next = None
return newHead
Partition Listhttps://leetcode.cn/problems/partition-list/Diff: MED
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def partition(self, head: Optional[ListNode], x: int) -> Optional[ListNode]:
# dummy1 store the value that less than x
# dummy2 store the value not less than x
dummy1 = cur1 = ListNode()
dummy2 = cur2 = ListNode()
cur = head
while cur:
if cur.val < x:
cur1.next = ListNode(cur.val)
cur1 = cur1.next
else:
cur2.next = ListNode(cur.val)
cur2 = cur2.next
cur = cur.next
cur1.next = dummy2.next
return dummy1.next
LRU Cachehttps://leetcode.cn/problems/lru-cache/Diff: MED
class Node:
def __init__(self, key=0, val=0):
self.key = key
self.val = val
self.pre = None
self.nxt = None
class LRUCache:
def __init__(self, capacity: int):
self.cache = {}
self.capacity = capacity
self.head = Node()
self.tail = Node()
self.head.nxt = self.tail
self.tail.pre = self.head
def _remove(self, node: Node):
post = node.nxt
prev = node.pre
prev.nxt = post
post.pre = prev
def _addFront(self, node: Node):
node.nxt = self.head.nxt
node.pre = self.head
self.head.nxt.pre = node
self.head.nxt = node
def get(self, key: int) -> int:
if key in self.cache:
node = self.cache[key]
self._remove(node)
self._addFront(node)
return node.val
return -1
def put(self, key: int, value: int) -> None:
if key in self.cache:
node = self.cache[key]
node.val = value
self._remove(node)
self._addFront(node)
else:
new_node = Node(key, value)
self.cache[key] = new_node
self._addFront(new_node)
if len(self.cache) > self.capacity:
lru_node = self.tail.pre
self._remove(lru_node)
del self.cache[lru_node.key]
# Your LRUCache object will be instantiated and called as such:
# obj = LRUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)
For the remaining types of problems, please refer to my channel.
everecursion-CSDN博客everecursion关注python,github,chatgpt领域.https://blog.csdn.net/gcsyymm?type=blog