imashutosh51

Kth smallest element in a sorted matrix

Oct 16th, 2022 (edited)
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.85 KB | None | 0 0
  1. '''
  2. Logic:
  3. We can declare a min heap and put first elements from all the columns along with cordinates.
  4. min heap will sort the elements based on the first component of each element.
  5. pop top element from min heap and put the next element from that column only.
  6. this way we will get elements one by one and return the kth element.
  7.  
  8. This method is better when range is big but we are allowed to have O(n) space.
  9. '''
  10.  
  11. from typing import List
  12. import heapq
  13.  
  14. class Solution:
  15.     def kthSmallest(self, matrix: List[List[int]], k: int) -> int:
  16.         n = len(matrix)
  17.        
  18.         # min heap: (value, row, col)
  19.         heap = []
  20.        
  21.         # push first row elements (one from each column)
  22.         for col in range(n):
  23.             heapq.heappush(heap, (matrix[0][col], 0, col))
  24.        
  25.         count = 0
  26.        
  27.         while heap:
  28.             val, row, col = heapq.heappop(heap)
  29.             count += 1
  30.            
  31.             if count == k:
  32.                 return val
  33.            
  34.             # push next element from same column
  35.             if row + 1 < n:
  36.                 heapq.heappush(heap, (matrix[row + 1][col], row + 1, col))
  37.        
  38.         return -1
  39.  
  40.  
  41. #M-2
  42. '''
  43. This is better when range is small but no extra space allowed.The approach is same as median in the row wise sorted matrix.
  44.  
  45. mid is not necessarily an element from the matrix, but it represents a value in the search space. By checking how many elements are ≤ mid and shrinking the range accordingly, the binary search converges to the smallest value for which count ≥ k, which is exactly the k-th smallest element in the matrix.
  46.  
  47. bisect_right(row, mid) returns the index where mid would be inserted on the right, which is equal to the number of elements ≤ mid in that row. For example, if row = [0, 1, 2] and mid = 5, then bisect_right(row, 5) = 3, meaning all 3 elements are ≤ mid.
  48.  
  49. T:C O(Nlog(N)*log(M)) m=range/space
  50. log(M) is for binary search as we are searching on a space of max-min of the matrix
  51. Nlog(N) is for each mid, we are doing binary search on each row ie. log(N) for each row and N times for N rows so N*log(N)
  52. '''
  53. import math
  54. from bisect import bisect_right
  55. def fun(matrix,target): #This tells how many elements are smaller or equal than the current elemnet
  56.     ans=0
  57.     for row in matrix:
  58.         ans+=bisect_right(row,target)
  59.     return ans
  60. class Solution:
  61.     def kthSmallest(self, matrix: List[List[int]], k: int) -> int:
  62.         l = matrix[0][0]
  63.         r = matrix[-1][-1]
  64.        
  65.         while l<=r:
  66.             mid= (l+r)//2
  67.             count=fun(matrix,mid)
  68.             if count>=k:
  69.                 r=mid-1
  70.             else:
  71.                 l=mid+1
  72.         return l #Mid was just a middle element, not an element from the matrix but you kept reducing when count is more or greater so it came down to the right element of the matrix.
  73.        
Advertisement
Add Comment
Please, Sign In to add comment