LeetCode Brushing Questions: Week Two
table of Contents
- LeetCode Brushing Questions: Week Two
-
- Preface
- Knowledge points
-
- 1. Linked list
- 2. The realization of singly linked list
-
- 1) Node implementation
- 2) Implementation of SinglelinkedList
- 3) Check whether the linked list is empty
- 4) add adds elements at the front end of the linked list
- 5) append adds elements to the end of the linked list
- 6) search to retrieve whether the element is in the linked list
- 7) The position of the index element in the linked list
- 8) remove deletes an element in the linked list
- 9) Insert an element in the insert list
- LeetCode example
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:
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:
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 :
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
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 :
# 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
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:
Input: head = [4,2,1,3]
Output: [1,2,3,4]
Example 2:
Input: head = [-1,5,3,4,0]
Output: [- 1,0,3,4,5]
Example 3:
Input: head = []
Output: []
Realize :
# 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
147. Insert Sort on Linked List
Insert sort on the linked list .
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 :
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
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 :
# 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的链表的末尾,也是当前这一段链表的头