Inhaltsverzeichnis
In diesem Artikel werden einige häufigere Fragen mit "K" im Titel aufgeführt. Einige Fragen werden in einem anderen Blog von mir ausführlich erläutert, sodass ich in diesem Artikel nicht zu viel erläutern werde.
Eine verknüpfte Liste
1. Geben Sie den k-ten Knoten von unten zurück
输入: 1->2->3->4->5 和 k = 2 输出: 4
class Solution:
def kthToLast(self, head: ListNode, k: int) -> int:
fast = head
slow = head
while k!=0:
fast = fast.next
k-=1
while fast:
fast = fast.next
slow = slow.next
return slow.val
Lassen Sie den schnellen Zeiger zuerst k Schritte und dann gleichzeitig gehen. Wenn der schnelle Zeiger das Ende erreicht, geht der langsame Zeiger zum k-ten Knoten.
2. K sortierte verknüpfte Listen zusammenführen
输入: [ 1->4->5, 1->3->4, 2->6 ] 输出: 1->1->2->3->4->4->5->6
class Solution:
def mergeKLists(self, lists: List[ListNode]) -> ListNode:
if not lists:return None
return self.helper(lists,0,len(lists)-1)
def helper(self,lists,l,r):
if l==r:
return lists[l]
# if l>r:
# return None
mid = l + (r - l) // 2
l1 = self.helper(lists,l,mid)
l2 = self.helper(lists,mid+1,r)
return self.mergeTwoList(l1, l2)
def mergeTwoList(self,A,B):
if not A or not B:
return B if not A else A
cur = ListNode(-1)
tmp = cur
while A and B:
if A.val<=B.val:
tmp.next = A
A = A.next
else:
tmp.next = B
B = B.next
tmp = tmp.next
tmp.next = A if A else B
return cur.next
Verwenden Sie die Dichotomie, um verknüpfte Listen paarweise zusammenzuführen
3. Eine Reihe von K Flip-Linked-Listen
class Solution:
def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
if not head or not head.next:
return head
tail = head
for i in range(k):
if not tail:
return head
tail = tail.next
newHead = self.reverse(head,tail)
head.next = self.reverseKGroup(tail,k)
return newHead
def reverse(self,start,end):
pre = None
while start!=end:
node = start.next
start.next = pre
pre = start
start = node
return pre
Bei Verwendung der rekursiven Methode wird k einmal invertiert, reicht jedoch nicht aus, um k zu invertieren. Sie können auch die Stapelmethode verwenden, um k Knoten in den Stapel zu verschieben und sie dann zum Hinzufügen zur Ergebnisliste hinzuzufügen.
class Solution:
def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
dummy = ListNode(0)
p = dummy
while True:
count = k
stack = []
tmp = head
while count and tmp:
stack.append(tmp)
tmp = tmp.next
count -= 1
# 注意,目前tmp所在k+1位置
# 说明剩下的链表不够k个,跳出循环
if count :
p.next = head
break
# 翻转操作
while stack:
p.next = stack.pop()
p = p.next
#与剩下链表连接起来
p.next = tmp
head = tmp
return dummy.next
Zweitens der Binärbaum
Der k-te größte Knoten des binären Suchbaums
输入: root = [3,1,4,null,2], k = 1 3 / \ 1 4 \ 2 输出: 4
Rekursive Version:
class Solution:
count = 0
res = 0
def kthLargest(self, root: TreeNode, k: int) -> int:
return self.helper(root,k)
def helper(self,root,k):
if not root:
return
self.helper(root.right,k)
self.count +=1
if k==self.count:
self.res = root.val
self.helper(root.left,k)
return self.res
Iterative Version:
class Solution:
def kthLargest(self, root: TreeNode, k: int) -> int:
if not root:
return None
stack = []
node = root
while node or len(stack)>0:
while node:
stack.append(node)
node = node.right
node = stack.pop()
if k==1:
self.res = node.val
k-=1
node = node.left
return self.res
Drei, das Präfix und
Die Summe ist ein Unterarray von K.
输入:nums = [1,1,1], k = 2 输出: 2 , [1,1] 与 [1,1] 为两种不同的情况。
Als ich die Frage zum ersten Mal sah, dachte ich, sie sei dieselbe wie die kombinierte Summenfrage .
输入: candidates = [2,3,6,7], target = 7, 所求解集为: [ [7], [2,2,3] ]
Also habe ich die Backtracking-Vorlage angewendet, natürlich war die endgültige Antwort falsch. Nachdem ich die Analyse gelesen hatte, stellte ich fest, dass die Präfixsumme verwendet wurde.
Was ist die Präfixsumme? Ist eigentlich die Summe der aktuellen Elemente im Array
Wörterbuch Schlüssel Präfix und, das heißt von 0 bis zur Summe des aktuellen Eintrags, der Wert der Entstehung von mehreren Werten für das Präfix und
vor der nums durchqueren wir Grenzen vorgegeben ( das heißt bereits erwähnt Präfixsumme [-1] = 0): Die Karte wird zunächst in ein 0: 1-Schlüssel-Wert-Paar eingefügt, dh die Präfixsumme von 0 ist so voreingestellt, dass sie einmal angezeigt wird.
Durchlaufen Sie jedes Element mit Zahlen, suchen Sie die Präfixsumme des aktuellen Elements und speichern Sie es in der Karte
Wäre vorher nicht vorhanden gewesen, wird gespeichert, ein Anfangswert wird
vorher durch den entsprechenden Wert von +1 gespeichert, d. H. Die Anzahl der Vorkommen +1
Seitenkantenansicht-Kartenspeicher, wenn der Schlüssel bereits in der Karte als aktuelles Präfix vorhanden ist und - k
Erklären Sie, dass es [vorher berechnete Präfixsumme] gibt und ihr Wert [aktuelle Präfixsumme] erfüllt - [zuvor berechnete Präfixsumme] == k
akkumuliert die Anzahl der Vorkommen von [zuvor berechnete Präfixsumme] im Zählzähler
class Solution:
def subarraySum(self, nums: List[int], k: int) -> int:
if not nums:
return 0
dic = dict()
dic[0] = 1
acc = 0
count = 0
for num in nums:
acc += num
if (acc-k) in dic:
count+=dic[acc-k]
if acc not in dic:
dic[acc] = 1
else:
dic[acc] += 1
return count
Viertens dynamische Planung
Diese Frage ähnelt tatsächlich der Frage nach der hässlichen Zahl . Hier wird die dynamische Programmiermethode verwendet. Natürlich kann auch die Heap-Methode verwendet werden. Die Heap-Verwendung wird hier nicht vorgestellt.
Dies ist der dp-Ansatz mit drei Zeigern
class Solution:
def getKthMagicNumber(self, k: int) -> int:
a,b,c = 0,0,0
dp = [1]*k
for i in range(1,k):
n1,n2,n3 = dp[a]*3,dp[b]*5,dp[c]*7
dp[i] = min(n1,n2,n3)
if dp[i]==n1:
a+=1
if dp[i]==n2:
b+=1
if dp[i]==n3:
c+=1
return dp[-1]
Fünf, Haufen sortieren
Der Inhalt dieses Kapitels zur Heap-Sortierung wurde in meinem Blog https://blog.csdn.net/Matrix_cc/article/details/106606612 vorgestellt , daher werde ich ihn hier nicht vorstellen.
Sechs, Array
Kombiniere k geordnete Arrays
Fügen Sie das erste Element jedes Arrays zum Heap hinzu, erstellen Sie einen kleinen oberen Heap, fügen Sie dann das oberste Element des Heaps hinzu und fügen Sie es dem res-Array hinzu. Fügen Sie dann das nächste Element des Arrays, das dem gepoppten Element entspricht, zum Heap hinzu und die Schleife ist abgeschlossen
L ist die Anzahl der Arrays, N ist die Anzahl der Elemente im Array
- Zeitliche Komplexität: Da jedes Element einmal gelesen werden muss, dh die maximale Anzahl von M * N beträgt, beträgt die Komplexität des Einfügens jedes Elements in den kleinsten Heap O (logL), dh die Gesamtkomplexität beträgt O ( L * NlogL)
- Die Speicherkomplexität ist: Behalten Sie die minimale Heap-Größe bei, die O (L) ist.
import heapq
from collections import deque
def list_merge(*lists):
# 入参判断, 这里直接pass
# 将所有链表转化为deque,方便使用popleft获取链表的最左元素及根据索引返回该索引对应的剩余链表
queues = [queue for queue in map(deque, lists)]
heap = []
# 初始化链表,该链表中的元素为元组, 各个链表的第一个元素及链表所在索引
for i, lst in enumerate(queues):
heap.append((lst.popleft(), i))
# 将链表转换成最小堆
heapq.heapify(heap)
# 链表: 用于存放每次获取的堆顶层元素
result = []
while heap:
# 将堆顶层元素出堆
value, index = heapq.heappop(heap)
# 将顶层元素追加
result.append(value)
# 根据索引获取对应链表的剩余元素
if queues[index]:
# 如果存在下一个元素,则将该元素及索引入堆
heapq.heappush(heap, (queues[index].popleft(), index))
return result
print(list_merge(*[[4, 8, 20], [100, 200, 350, 370], [5, 8, 350, 500, 1000]]))
Referenz:
Einige Erklärungen in der Leetcode-Lösung