K Closest Points to Origin - Heap / Priority Queue - Leetcode 973 - Python

Sdílet
Vložit
  • čas přidán 27. 07. 2024
  • 🚀 neetcode.io/ - A better way to prepare for Coding Interviews
    🐦 Twitter: / neetcode1
    🥷 Discord: / discord
    🐮 Support the channel: / neetcode
    ⭐ BLIND-75 PLAYLIST: • Two Sum - Leetcode 1 -...
    💡 CODING SOLUTIONS: • Coding Interview Solut...
    💡 DYNAMIC PROGRAMMING PLAYLIST: • House Robber - Leetco...
    🌲 TREE PLAYLIST: • Invert Binary Tree - D...
    💡 GRAPH PLAYLIST: • Course Schedule - Grap...
    💡 BACKTRACKING PLAYLIST: • Word Search - Backtrac...
    💡 LINKED LIST PLAYLIST: • Reverse Linked List - ...
    💡 BINARY SEARCH PLAYLIST: • Binary Search
    Problem Link: neetcode.io/problems/k-closes...
    0:00 - Read the problem
    4:23 - Drawing Explanation
    7:00 - Coding Explanation
    leetcode 973
    This question was identified as a facebook interview question from here: github.com/xizhengszhang/Leet...
    #sorted #heap #python
    Disclosure: Some of the links above may be affiliate links, from which I may earn a small commission.
  • Věda a technologie

Komentáře • 106

  • @sushilkhadka8069
    @sushilkhadka8069 Před 2 lety +37

    I did not know we can heapify the a list list. Thanks man!

  • @nathantokala5643
    @nathantokala5643 Před 2 lety +42

    Thanks!

    • @nathantokala5643
      @nathantokala5643 Před 2 lety +37

      Got an offer from FB, this question was the technical screen! Thanks again for the great content

    • @NeetCode
      @NeetCode  Před 2 lety +34

      Hey Nathan congrats on FB, it's so awesome your hard word paid!!!!
      Thank you so much for the support, I really appreciate it! 😊

    • @pelusemua8425
      @pelusemua8425 Před 2 lety +1

      Hey! Congrats on your offer. Would you mind if I ask you personally thru other platforms? How to contact you?

    • @observer698
      @observer698 Před 2 lety +1

      Hi Nathan, for what position was this asked? Looking for ML position questions, if anyone has any experience please share

  • @symbol767
    @symbol767 Před 2 lety +6

    Great explanation, thank you

  • @mingjuhe1514
    @mingjuhe1514 Před 2 lety +2

    It's me again. Thank you NeetCode.

  • @nicolasguillenc
    @nicolasguillenc Před 6 měsíci +2

    I really like this problem, your explanation helped me really understand it. As a js developer I would like to know how to implement a heap during the interview, otherwise I will have to use a sorted array

    • @Reck1025
      @Reck1025 Před 3 měsíci

      Leetcode lets you use priority queues(same as min/max heap) from `datastructures-js/priority-queue`. Hopefully in an interview environment you can use something like this package or just explain that the sorted array will act as a heap.

  • @mikedelta658
    @mikedelta658 Před 6 měsíci

    Such a clear and efficient explanation

  • @shahidshahmeer
    @shahidshahmeer Před 3 lety +80

    Hey, I love your videos but this is not the most optimal, or even the 2nd most optimal solution.
    You can improve this solution by having a min heap of size k. Then, go through the list of points and add to the heap. If the size of the heap exceeds k, pop from the heap. By the end, your heap will contain the k closest points. This is O(nlogk) time (which is similar to your solution) but only O(k) space, whereas your solution is O(n) space.
    There is also an O(n) solution based on quick sort called quick select.

    • @rachitsingh8040
      @rachitsingh8040 Před 2 lety

      This may not work for cases where the closest point to the origin is at an index>k.

    • @gotemlearning
      @gotemlearning Před 2 lety +44

      wait if you have a min-heap and pop from it whenever size exceeds k you will just end up popping the closest points because you popped the smallest distance (min heap has min at top) -- instead use a max heap by adding -distance,x,y to the heap, then you will be left with k smallest distance (closest points) - but otherwise, you are correct

    • @mearaftadewos8508
      @mearaftadewos8508 Před 2 lety

      we can optimize the solution by pushing each values to the like heappush(res, [d, x, y]) => o(n) as we do the distance rather than going through the res list one moretime. But, you way I thought of it the first time but it is not possible b/c the problem statement need the only closest. So, we need to fine all of the closest and return k many of them.

    • @kuangyimeng8850
      @kuangyimeng8850 Před 2 lety +19

      That's correct. Keeping a heap of size k can make time complexity to O(nlogk). But, I think we should make a MAX HEAP of size k rather than a min-heap. Then, when an element 'x' comes in, we just compare if 'x' is smaller than the largest element in the max heap( the top one.) or not. If x is smaller, We can drop the previous top element away and add 'x' to our max heap.

    • @andrepinto7895
      @andrepinto7895 Před 2 lety +2

      OP certainly meant max heap, not min heap. This uses less memory, but in my case actually takes longer (I guess because of the extra remove operations while adding). It depends on the input. Time complexity is the same.

  • @littlebox4328
    @littlebox4328 Před 2 lety +28

    just wondering will be allowed that we use this kind of build-in function like heapify in the interview? BTW I have been watching your videos for a while, it is really really really helpful!

    • @MrRichiban
      @MrRichiban Před 2 lety +22

      I'm sure you would; it wouldn't be reasonable to expect the candidate to write the heap functions as part of another algorithm in a 20-minute interview!

    • @BbB-vr9uh
      @BbB-vr9uh Před 2 lety +9

      You can generally use builtins in an interview. If you can use the built-in dictionary, why not the built-in heap?

  • @activelylazy9993
    @activelylazy9993 Před rokem

    If we replace the append heap line with heappush and remove the heapify completely, time complexity for that for loop will be O(nlogn) i.e n times heappop is nlogn. Right?
    So this following logic this worse than appending and heapify, right? Kinda counter-intuitive!
    heap = []
    # for loop is n time logn
    for p in points:
    x,y = p
    d = x**2 + y**2
    heappush(heap,[d,x,y])
    res = []
    # k time logn
    while k:
    d,x,y = heappop(heap)
    res.append([x,y])
    k-=1
    return res

  • @grasstoucher856
    @grasstoucher856 Před rokem +5

    I just realize you sound like daily dose of internet

  • @kwakukusi4094
    @kwakukusi4094 Před 2 lety +13

    i got this in an amazon interview . I just sorted the array by distance and selected the first K elements. (not the best solution but it passed all the test cases)

    • @appcolab
      @appcolab Před 2 lety

      Was it online assessment? Onside the interviewer will ask you to optimise it

    • @kwakukusi4094
      @kwakukusi4094 Před 2 lety +4

      @@appcolab it was online assessment but I solved the question again on leetcode using the same method and it was pretty efficient (faster than 93%)

    • @appcolab
      @appcolab Před 2 lety

      Awesome, did you go on to clear the onsite interviews?

    • @kwakukusi4094
      @kwakukusi4094 Před 2 lety +5

      @@appcolab I am still in the interview process I just did my phone interview and I am awaiting the results

    • @appcolab
      @appcolab Před 2 lety

      All the best!!

  • @Ved3sten
    @Ved3sten Před 10 měsíci +3

    Can you explain how heapify is O(n)? To build a binary heap, don't you need to call heap reorder n times making it O(nlog(n))?

    • @ZhenglinLi
      @ZhenglinLi Před 9 měsíci +1

      Each time intset a element to hep is log(N), there are n elements to insert. So the maximum upper bound for time complexity is O(NlogN). However, after doing math calculations, the approximate time complexity is O(N) instead. This involves math calculations, and all you need to know is that to build a heap, the time complexity is O(N). That's enough.

  • @xmnemonic
    @xmnemonic Před rokem +1

    such a bizarre problem. they might as well just give you an array of ints and ask you to heap sort it

  • @zeptra17
    @zeptra17 Před 12 dny

    i dont know how you come up with this kind of solutions, wow

  • @upendrakumar-bw1jd
    @upendrakumar-bw1jd Před měsícem

    If we are using heaps then we do heapify on distance values then it tooks O(n) time and for k pop operations we need klog(n) time right I.e total time is n+klog(n) .
    But if we use arrays it took O(nlogn) time and for k pop operations it tooks constant time right. I.e total time is nlogn only .
    Is nlogn is really greater than n+klogn

  • @sahithrao2163
    @sahithrao2163 Před 3 lety +2

    Can you explain bounded robot in the next video?

  • @oxyht
    @oxyht Před měsícem

    Why do heappop? Direct use indexing. O(n + k) solution

  • @prakhar242
    @prakhar242 Před rokem

    How did python automatically use min heap? Didn't you say in another video that Python only supports max heap, and to use min heap we have to use the negative values?

    • @lea7802
      @lea7802 Před rokem +3

      It was the opposite, python has min heap and we had to use the negative to simulate a max heap

  • @alxzheng
    @alxzheng Před 2 lety +5

    how does heapify know what its key is?

    • @world11191
      @world11191 Před 6 měsíci

      i haven't checked, but i imagine it goes left to right in the same way sorting does if you pass in an iterable of tuples. Compare index 0's and if they are the same, then only compare index 1's, and so on.

  • @FaizanShaikh-zg9to
    @FaizanShaikh-zg9to Před rokem +1

    Hey can we just use lambda function to store the key value than sort it and then just remove elements after bigger then k
    def kClosest(self, points: List[List[int]], k: int) -> List[List[int]]:
    points.sort(key = lambda x: x[0]**2 + x[1]**2)
    return points[:k]

    • @jwsoftware
      @jwsoftware Před rokem +1

      Sounds like the sort approach would be O(nlogn) but the heap approach would be O(n). But yeah the sort approach is way faster than the heap approach on leetcode

    • @vengalrao5772
      @vengalrao5772 Před 11 měsíci

      ​@@jwsoftwaresame doubt man. Do I need to learn heap now ? Or should I go on with the sorting ?
      I was looking for this comment desperately.
      You suggest is valuable

    • @Exploshi
      @Exploshi Před 4 měsíci

      why is it faster if O(nlogn) is slower than O(n)?@@jwsoftware

  • @CodingForRealLife
    @CodingForRealLife Před 3 lety +17

    The first part is O(N logN), looping through the points array then add it to heap, a better solution would be using max heap, this will improve the solution to O(N logK)

    • @megharamanathan5997
      @megharamanathan5997 Před 2 lety +12

      The first part is actually O(N) because at that point in the code, minHeap wasn't turned into a heap yet. It was still a list, so appending to the list was an O(1) operation

    • @jerrylin4980
      @jerrylin4980 Před 2 lety

      @@megharamanathan5997 So it takes O(1) * n to append. Then heapify takes O(nlogn).
      heappop k times takes O(klogn). Is that correct?

    • @studyaccount794
      @studyaccount794 Před 2 lety +1

      @@megharamanathan5997 But he's still sorting the array to get the answer. Sorting takes nlogn

    • @david_trey5523
      @david_trey5523 Před rokem +4

      @@studyaccount794 I would not say so. If you already have a all your elements, you can turn that list into a heap in linear time. Second he isn’t popping N elements of the list only K. That means the efficiency would still be (N + Klog(N))

    • @sampannapokhrel
      @sampannapokhrel Před 11 měsíci

      @@david_trey5523 How could you convert a list to min heap in O(n)?

  • @rohitdeepakphadke9442
    @rohitdeepakphadke9442 Před 2 lety

    u r a god!

  • @smartwork7098
    @smartwork7098 Před 17 dny

    I solved this problem using sorting.

  • @jonaskhanwald566
    @jonaskhanwald566 Před 3 lety +3

    Can anyone explain, actually where we have to use Heap / Priority Queue? For this problem, time complexity of both normal sorting and minheap are same

    • @YeetYeetYe
      @YeetYeetYe Před 2 lety +4

      In the worst case you are correct, but minheap will be faster in the average case where k != n. Heapify operation does NOT take nlogn time, it takes n time. So the overall complexity of the minheap solution is O(n + klogn) , whereas with sorting it's O(nlogn)

    • @xalizalizx
      @xalizalizx Před rokem +1

      @@YeetYeetYe Why does Heapify operation take n time? Isn't heap insertion log n? and doing that n times is basically "n log n"?

    • @YeetYeetYe
      @YeetYeetYe Před rokem

      @@xalizalizx I would highly recommend this video as an explanation: czcams.com/video/MiyLo8adrWw/video.html&ab_channel=AlgorithmswithAttitude

    • @nikhil_a01
      @nikhil_a01 Před rokem

      heapify doesn't just insert N times. It uses Floyd's algorithm which is O(N). The intuition is that binary trees are bottom heavy; in a 15 node tree, 12 of the nodes are in the bottom two levels, and only 3 are on the top two levels. The bottom nodes don't have to be moved far to heapify. The top nodes might have to move further but there are fewer of them. If you actually count how many nodes have to be moved and sum it up , it works out to O(N) in the end.

  • @GingeBreadBoy
    @GingeBreadBoy Před rokem +5

    Quick Select with Random Selects, O(N) average time. I chose quick select here because all data was present (no stream) and we are not performing any transformative operations on the actual inputs (as in last stone weight).
    """
    We have points Xi, Yi, and an integer k.
    We want the K-closest points to the origin.
    We could use a heap to solve this problem in O(NLogN) (heapify plus popping...)
    However a better solution will be to use quick select which gets an average case runtime of O(N) time!
    The closests points will have smallest euclidean distances ...
    """
    class Solution:
    def kClosest(self, points: List[List[int]], k: int) -> List[List[int]]:
    def partition(l,r):
    #choose a random pivot
    pivot = random.randint(l,r)
    pivot_distance = euclidean_distance(points[pivot])
    #move pivot to end
    points[pivot], points[r] = points[r], points[pivot]
    #store idx for swapping
    store_idx = l
    for i in range(l,r):
    if euclidean_distance(points[i]) < pivot_distance:
    points[i], points[store_idx] = points[store_idx], points[i]
    store_idx += 1
    #switch store_idx with pivot
    points[r], points[store_idx] = points[store_idx], points[r]
    return store_idx

    def quick_select(points,k):
    left, right = 0, len(points)-1
    pivot_idx = len(points)
    #continue parititoning while pivot != k
    while pivot_idx != k:
    pivot_idx = partition(left, right)
    #k smallest lie to the left
    if pivot_idx > k:
    right = pivot_idx - 1
    #the k smallseet lie to the right & to the left of pivot_idx all values smaller, so left = pivot_idx
    else:
    left = pivot_idx
    #return k closest points
    return points[:k]
    def euclidean_distance(point):
    x,y = point
    return math.sqrt(x**2+y**2)
    #perform quick select and return k smallest
    return quick_select(points, k)

  • @dheerajgadwala8874
    @dheerajgadwala8874 Před 2 lety +3

    Time Complexity: O(n + klog(n)) right?

    • @YeetYeetYe
      @YeetYeetYe Před 2 lety +2

      Yup. In the case where k = n, this is actually worse than sorting.

  • @pwnweb5734
    @pwnweb5734 Před 2 lety +2

    There is actually a O(N) solution too for this

  • @xpstarter
    @xpstarter Před měsícem

    Correction: Heapify is O(logn), here its refering to build heap which is O(n)

  • @z.l.588
    @z.l.588 Před 2 lety +4

    this could actually be solved using quick select in O(n) and O(1), not sure if heap solution is acceptable in an f and g equivalent interview

    • @PeachHeartBlog
      @PeachHeartBlog Před 2 lety +4

      It looks like quick select gives me time exceed limit due to a lot of duplicates in the list

  • @siddhantsehgal9900
    @siddhantsehgal9900 Před 3 lety +1

    Hey! Can you do Kth largest element in an array? Thanks for this video!

    • @CEOofTheHood
      @CEOofTheHood Před 3 lety +2

      its the exact same question as this.

    • @stan8851
      @stan8851 Před 3 lety +1

      just use a maxheap instead of the minheap

    • @mearaftadewos8508
      @mearaftadewos8508 Před 2 lety

      just store the negative value of the distance in to the heap

  • @adityahpatel
    @adityahpatel Před 3 měsíci

    why is it obvious that we need to pop k times?

  • @spes9850401
    @spes9850401 Před rokem +2

    5:31 why did you re-draw the circle

  • @gyan2664
    @gyan2664 Před 2 lety +1

    your approach has complexity of nlogn thus heap power is unused
    complexity is suppose to be nlogk checkout below
    from heapq import heapify, heappush, heappop
    from math import sqrt
    class Solution:
    def kClosest(self, points: List[List[int]], k: int) -> List[List[int]]:
    x = []
    i = 0
    while(i < k):
    first = points[i][0]
    second = points[i][1]
    heappush(
    x, (-sqrt(first*first+ second*second), points[i])
    )
    i += 1
    while(len(points) > i):
    first = points[i][0]
    second = points[i][1]
    heappush(x, (-sqrt(first*first+ second*second), points[i]))
    heappop(x)
    i = i+1
    answer = []
    for i, j in x:
    answer.append(j)
    return answer

    • @minciNashu
      @minciNashu Před 2 lety

      There's no need for actual SQRT, all you need is the squares for comparisons.
      Those SQRTs actually hurt performance alot.

  • @JulianBoilen
    @JulianBoilen Před 2 lety

    This screams QuickSelect to me

    • @BbB-vr9uh
      @BbB-vr9uh Před 4 měsíci

      Share the code plz if you do it

  • @superfahd
    @superfahd Před rokem

    I don't understand the running time of this. Adding an element to a heap is O(log N). Doing this for N elements is O(N log N). Popping from the Heap K times is O (K log N). Since K < N, the total running time should be O(N long N)

  • @xxRAP13Rxx
    @xxRAP13Rxx Před 9 měsíci

    There is a faster max heap solution. There is also an on-average O(N) solution using quick select as described here: czcams.com/video/8F4H1G2MmY8/video.html

    • @xxRAP13Rxx
      @xxRAP13Rxx Před 9 měsíci

      Apologies. The quick select solution now gives a TLE on LeetCode because of a pathological testcase. But the max heap solution is still good.

  • @adityahpatel
    @adityahpatel Před 3 měsíci

    You need to white board till u arrive at the solution (and NOT leave it halfway) before you jump to the coding section.

  • @algorithmo134
    @algorithmo134 Před 3 lety

    Why is the video quality so bad?

    • @appcolab
      @appcolab Před 2 lety +2

      Please, just make sure your internet connection is strong then select 720p quality.

  • @ma_sundermeyer
    @ma_sundermeyer Před rokem +2

    Got the N*log(K) solution. But remember not to apply leetcode style programming in real life, especially not in python. Exploit numpy parallelism/vectorization instead of using sequential loops:
    points = np.array(points)
    dists = np.linalg.norm(points, axis=1)
    k_indices = np.argpartition(dists, k-1)[:k]
    return points[k_indices].tolist()
    Faster than 95% of leetcode solutions, although with huge variance since their timing system is broken.

  • @roguenoir
    @roguenoir Před 2 lety +1

    Would my 1 line solution be cheating?
    return heapq.nsmallest(k, points, key=lambda x: x[0]*x[0] + x[1]*x[1])
    Runtime: 1071 ms, faster than 64.20% of Python3 online submissions for K Closest Points to Origin.
    Memory Usage: 20.3 MB, less than 79.53% of Python3 online submissions for K Closest Points to Origin.

    • @minciNashu
      @minciNashu Před 2 lety

      actually, heapify is faster than nsmallest

  • @poojankhanpara
    @poojankhanpara Před 2 lety +4

    Thanks!

    • @NeetCode
      @NeetCode  Před 2 lety +1

      Hey Poojan - thank you so much, I really appreciate it!! 😊

    • @poojankhanpara
      @poojankhanpara Před 2 lety +1

      @@NeetCode I am a fan of your videos, pls keep it up!