Fragen zu "K" im Interviewalgorithmus und in der Datenstruktur

Inhaltsverzeichnis

Eine verknüpfte Liste

Zweitens der Binärbaum

Drei, das Präfix und

Viertens dynamische Planung

Fünf, Haufen sortieren

Sechs, Array


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

K Nummer

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

Ich denke du magst

Origin blog.csdn.net/Matrix_cc/article/details/106636321
Empfohlen
Rangfolge