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

Поделиться
HTML-код
  • Опубликовано: 8 окт 2024

Комментарии • 110

  • @sushilkhadka8069
    @sushilkhadka8069 2 года назад +45

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

  • @nathantokala5643
    @nathantokala5643 3 года назад +48

    Thanks!

    • @nathantokala5643
      @nathantokala5643 3 года назад +41

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

    • @NeetCode
      @NeetCode  3 года назад +38

      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 2 года назад +1

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

    • @observer698
      @observer698 2 года назад +1

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

  • @nicolasguillenc
    @nicolasguillenc 8 месяцев назад +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 6 месяцев назад

      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.

  • @shahidshahmeer
    @shahidshahmeer 3 года назад +88

    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 2 года назад

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

    • @gotemlearning
      @gotemlearning 2 года назад +46

      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 2 года назад

      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 2 года назад +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 2 года назад +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.

  • @kwakukusi4094
    @kwakukusi4094 2 года назад +15

    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 2 года назад +1

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

    • @kwakukusi4094
      @kwakukusi4094 2 года назад +5

      @@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 2 года назад

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

    • @kwakukusi4094
      @kwakukusi4094 2 года назад +5

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

    • @appcolab
      @appcolab 2 года назад

      All the best!!

  • @littlebox4328
    @littlebox4328 3 года назад +30

    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 2 года назад +23

      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 2 года назад +9

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

    • @guinea_horn
      @guinea_horn Месяц назад

      @@MrRichiban Well there are non-heap based approaches like just sorting the list like he said in the video. Even still, in most cases you'd be able to use libraries like heapq in an interview - if you for some reason can't then just sort the list.

  • @symbol767
    @symbol767 2 года назад +6

    Great explanation, thank you

  • @grasstoucher856
    @grasstoucher856 Год назад +7

    I just realize you sound like daily dose of internet

  • @mingjuhe1514
    @mingjuhe1514 2 года назад +2

    It's me again. Thank you NeetCode.

  • @mikedelta658
    @mikedelta658 8 месяцев назад

    Such a clear and efficient explanation

  • @Ved3sten
    @Ved3sten Год назад +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 11 месяцев назад +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.

  • @zeptra17
    @zeptra17 2 месяца назад

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

  • @CodingForRealLife
    @CodingForRealLife 3 года назад +20

    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 3 года назад +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 2 года назад

      @@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 2 года назад +1

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

    • @david_trey5523
      @david_trey5523 2 года назад +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 Год назад

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

  • @upendrakumar-bw1jd
    @upendrakumar-bw1jd 4 месяца назад

    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

  • @alxzheng
    @alxzheng 2 года назад +5

    how does heapify know what its key is?

    • @world11191
      @world11191 8 месяцев назад +1

      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.

  • @xmnemonic
    @xmnemonic Год назад +1

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

  • @GingeBreadBoy
    @GingeBreadBoy Год назад +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)

  • @activelylazy9993
    @activelylazy9993 Год назад

    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

  • @oxyht
    @oxyht 4 месяца назад

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

  • @FaizanShaikh-zg9to
    @FaizanShaikh-zg9to Год назад +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 Год назад +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 Год назад

      ​@@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 7 месяцев назад

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

  • @z.l.588
    @z.l.588 2 года назад +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 2 года назад +5

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

  • @rachelwilliams8569
    @rachelwilliams8569 Месяц назад

    When solving this problem in Ruby, sorting the distances without a min heap was faster.

  • @smartwork7098
    @smartwork7098 2 месяца назад

    I solved this problem using sorting.

  • @dheerajgadwala8874
    @dheerajgadwala8874 2 года назад +3

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

    • @YeetYeetYe
      @YeetYeetYe 2 года назад +2

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

  • @sahithrao2163
    @sahithrao2163 3 года назад +2

    Can you explain bounded robot in the next video?

  • @prakhar242
    @prakhar242 Год назад

    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 Год назад +3

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

  • @spes9850401
    @spes9850401 Год назад +2

    5:31 why did you re-draw the circle

  • @rohitdeepakphadke9442
    @rohitdeepakphadke9442 3 года назад

    u r a god!

  • @superfahd
    @superfahd Год назад

    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)

  • @jonaskhanwald566
    @jonaskhanwald566 3 года назад +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 2 года назад +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 2 года назад +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 2 года назад

      @@xalizalizx I would highly recommend this video as an explanation: ruclips.net/video/MiyLo8adrWw/видео.html&ab_channel=AlgorithmswithAttitude

    • @nikhil_a01
      @nikhil_a01 Год назад

      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.

  • @xpstarter
    @xpstarter 3 месяца назад

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

  • @pwnweb5734
    @pwnweb5734 2 года назад +2

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

  • @adityahpatel
    @adityahpatel 6 месяцев назад

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

  • @siddhantsehgal9900
    @siddhantsehgal9900 3 года назад +1

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

    • @CEOofTheHood
      @CEOofTheHood 3 года назад +2

      its the exact same question as this.

    • @stan8851
      @stan8851 3 года назад +1

      just use a maxheap instead of the minheap

    • @mearaftadewos8508
      @mearaftadewos8508 2 года назад

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

  • @gyan2664
    @gyan2664 2 года назад +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 2 года назад

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

  • @ma_sundermeyer
    @ma_sundermeyer 2 года назад +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.

  • @JulianBoilen
    @JulianBoilen 2 года назад

    This screams QuickSelect to me

    • @BbB-vr9uh
      @BbB-vr9uh 7 месяцев назад

      Share the code plz if you do it

  • @xxRAP13Rxx
    @xxRAP13Rxx 11 месяцев назад

    There is a faster max heap solution. There is also an on-average O(N) solution using quick select as described here: ruclips.net/video/8F4H1G2MmY8/видео.html

    • @xxRAP13Rxx
      @xxRAP13Rxx 11 месяцев назад

      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 6 месяцев назад

    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 3 года назад

    Why is the video quality so bad?

    • @appcolab
      @appcolab 2 года назад +2

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

  • @roguenoir
    @roguenoir 2 года назад +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 2 года назад

      actually, heapify is faster than nsmallest

  • @poojankhanpara
    @poojankhanpara 3 года назад +4

    Thanks!

    • @NeetCode
      @NeetCode  3 года назад +1

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

    • @poojankhanpara
      @poojankhanpara 3 года назад +1

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