LeetCode Top Interview 150 - Linked List

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.

Node Structure:

  • Singly Linked List Node:

    • It usually consists of two parts:
      • Data part: Stores the data element to be saved.
      • Pointer part: Stores the reference (usually the memory address) to the next node.
class Node:
    def __init__(self, data=None):
        self.data = data
        self.next = None

Doubly Linked List Node:

  • It contains three parts:
    • Data part: Stores the data element to be saved.
    • Forward pointer part: Stores the reference to the previous node.
    • Backward pointer part: Stores the reference to the next 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 Cycle 

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 Numbers

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 Lists 

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 Pointer

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 II

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-Group 

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 List

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 II

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 List

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 List

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 Cache

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

你可能感兴趣的:(leetcode,算法,职场和发展,开源,python,数据结构)