LeetCode Brushing Questions: Week Two

LeetCode Brushing Questions: Week Two


Related series of notes:
LeetCode Brushing Questions: Preface
LeetCode Brushing Questions: First Week
LeetCode Brushing Questions: Second Week

Preface

  This week’s Topic is [Linked list], the corresponding 5 questions:
    22. Return the kth node from the
    bottom 21. Merge two ordered linked lists
    148. Sort linked lists
    147. Insert and sort the linked lists
    25. A set of K flipped linked lists

Knowledge points

1. Linked list

  A linked list is a collection of data items, where each data item is a part of a node, and each node also contains a link to the next node.

  The structure of the nodes of the linked list is as follows:
Insert picture description here
  data is customized data, and next is the address of the next node.

  According to the structure, the linked list can be divided intoSingly linked list, one-way circular linked list, doubly linked list, two-way circular linked listWait. Among them, the structure of the singly linked list and the singly circular linked list is shown in the following figure:

Insert picture description here

2. The realization of singly linked list

1) Node implementation

  Each Node is divided into two parts. One part contains the elements of the linked list, which can be called the data field; the other part is a pointer to the next Node.

class Node():
    __slots__=['_item','_next']    #限定Node实例的属性
    def __init__(self,item):
        self._item=item
        self._next=None     #Node的指针部分默认指向None
    def getItem(self):
        return self._item
    def getNext(self):
        return self._next
    def setItem(self,newitem):
        self._item=newitem
    def setNext(self,newnext):
        self._next=newnext

2) Implementation of SinglelinkedList

class SingleLinkedList():  
    def __init__(self):
        self._head=None    #初始化链表为空表
        self._size=0

3) Check whether the linked list is empty

def isEmpty(self):
    return self._head==None 

4) add adds elements at the front end of the linked list

def add(self,item):
    temp=Node(item)
    temp.setNext(self._head)
    self._head=temp

5) append adds elements to the end of the linked list

def append(self,item):
    temp=Node(item)
    if self.isEmpty():
        self._head=temp   #若为空表,将添加的元素设为第一个元素
    else:
        current=self._head
        while current.getNext()!=None:
            current=current.getNext()   #遍历链表
        current.setNext(temp)   #此时current为链表最后的元素

6) search to retrieve whether the element is in the linked list

def search(self,item):
    current=self._head
    founditem=False
    while current!=None and not founditem:
        if current.getItem()==item:
            founditem=True
        else:
            current=current.getNext()
    return founditem

7) The position of the index element in the linked list

def index(self,item):
    current=self._head
    count=0
    found=None
    while current!=None and not found:
        count+=1
        if current.getItem()==item:
            found=True
        else:
            current=current.getNext()
    if found:
        return count
    else:
        raise ValueError,'%s is not in linkedlist'%item

8) remove deletes an element in the linked list

def remove(self,item):
    current=self._head
    pre=None
    while current!=None:
        if current.getItem()==item:
            if not pre:
                self._head=current.getNext()
            else:
                pre.setNext(current.getNext())
            break
        else:
            pre=current
            current=current.getNext()

9) Insert an element in the insert list

def insert(self,pos,item):
   if pos<=1:
       self.add(item)
   elif pos>self.size():
       self.append(item)
   else:
       temp=Node(item)
       count=1
       pre=None
       current=self._head
       while count<pos:
           count+=1
           pre=current
           current=current.getNext()
       pre.setNext(temp)
       temp.setNext(current)

LeetCode example

22. Bracket generation

  The number n represents the logarithm of generating brackets. Please design a function to generate all possible and effective bracket combinations .
    Example:
    Input: n = 3
    Output: [
       “((()))”,
       “(()())”,
       “(())()”,
       “()(())”,
       “()( )()”
       ]

  Realize :
Insert picture description here

class Solution:
    def generateParenthesis(self, n: int) -> List[str]:
        #回溯法
        result = []
        def backtrack(left, right, tmp):
            if right > left or left > n: return
            if left + right == 2 * n:
                result.append(tmp)
                return
            backtrack(left + 1, right, tmp + '(')
            backtrack(left, right + 1, tmp + ')')
        backtrack(0, 0, '')
        return result

Insert picture description here

21. Merge two ordered linked lists

  Combine two ascending linked lists into a new ascending linked list and return. The new linked list is composed by splicing all the nodes of the given two linked lists .
     Example:
      Input: 1->2->4, 1->3->4
      Output: 1->1->2->3->4->4

  Realize :
Insert picture description here

# 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, l1: ListNode, l2: ListNode) -> ListNode:
        # 递归
        if l1 and l2:
            if l1.val > l2.val: 
                l1, l2 = l2, l1
            l1.next = self.mergeTwoLists(l1.next, l2)
        return l1 or l2

Insert picture description here

148. Sort Linked List

  Give you the head node of the linked list, please sort it in ascending order and return to the sorted linked list .
  Advanced:
    • Can you sort the linked list in O(n log n) time complexity and constant level space complexity?
       Example 1:
Insert picture description here
        Input: head = [4,2,1,3]
        Output: [1,2,3,4]
      Example 2:
Insert picture description here
        Input: head = [-1,5,3,4,0]
        Output: [- 1,0,3,4,5]
      Example 3:
        Input: head = []
        Output: []

  Realize :
Insert picture description here

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def sortList(self, head: ListNode) -> ListNode:
        # 使用快慢指针寻找链表中点,分解链表,递归融合2个有序链表
        if not (head and head.next): 
            return head

        pre, slow, fast = None, head, head
        while fast and fast.next: 
            pre, slow, fast = slow, slow.next, fast.next.next
        pre.next = None
        return self.mergeTwoLists(*map(self.sortList, (head, slow)))
    
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        if l1 and l2:
            if l1.val > l2.val: l1, l2 = l2, l1
            l1.next = self.mergeTwoLists(l1.next, l2)
        return l1 or l2

Insert picture description here

147. Insert Sort on Linked List

  Insert sort on the linked list .
Insert picture description here
     The animation demonstration of insertion sort is as above. Starting from the first element, the linked list can be considered partially sorted (indicated in black).
    At each iteration, an element (indicated in red) is removed from the input data and inserted in-situ into the sorted linked list.
     Insertion sorting algorithm:
       1. Insertion sorting is iterative, moving only one element at a time until all elements can form an ordered output list.
       2. In each iteration, insertion sort only removes one element to be sorted from the input data, finds its proper position in the sequence, and inserts it.
       3. Repeat until all input data is inserted.
     Example 1:
       Input: 4->2->1->3
       Output: 1->2->3->4
    Example 2:
       Input: -1->5->3->4->0
       Output: -1 ->0->3->4->5

  Realize :
Insert picture description here

class Solution:
    def insertionSortList(self, head: ListNode) -> ListNode:
        # 找个排头
        dummy = ListNode(-1)
        pre = dummy
        # 依次拿head节点
        cur = head
        while cur:
            # 把下一次节点保持下来
            tmp = cur.next
            # 找到插入的位置
            while pre.next and pre.next.val < cur.val:
                pre = pre.next
            # 进行插入操作
            cur.next = pre.next
            pre.next = cur
            pre= dummy
            cur = tmp
        return dummy.next

Insert picture description here

25. A set of K flip linked lists

  Give you a linked list, every k nodes are flipped, please return to the flipped linked list.
    k is a positive integer, and its value is less than or equal to the length of the linked list.
    If the total number of nodes is not an integral multiple of k, please keep the last remaining nodes in the original order.
       Example:
        Give you this linked list: 1->2->3->4->5
        When k = 2, it should return: 2->1->4->3->5
        When k = 3, it should return : 3->2->1->4->5

  Realize :
Insert picture description here

# 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: ListNode, k: int) -> ListNode:
        tmp = head
        for _ in range(k):         # 判断从当前节点起,够不够k个节点   【递归的终止条件】
            if tmp == None:        # 不够则后续节点都不用变动
                return head
            tmp = tmp.next
            
        # 设置两个指针             # 经过上面的终止条件后,下面要做的就是将一段长度为k的链表反转
        p, rev = head, None        # 起始情况 rev   p      ➡       走一步后   rev   p 
        for _ in range(k):         #         None   p0->p1->...pk-1    None <- p0   p1->...pk-1
            rev, rev.next, p = p, rev, p.next # 最终指针p指向pk-1.next, 也就是下一段的入口
        head.next = self.reverseKGroup(p, k)  # 进行递归             【递归入口】  
        return rev                 # rev恰好是原来长度为k的链表的末尾,也是当前这一段链表的头

Insert picture description here

Guess you like

Origin blog.csdn.net/weixin_42691585/article/details/115008627