class Solution:
    def kSmallestPairs(self, A: List[int], B: List[int], k: int) -> List[List[int]]:
        """tc O(KlgK)  sc O(K)
        main idea: min PQ,   (pair_sum,i_A,j_B) 
        constrains: (1) for each array, we consider at most k elements 
                    (2) for each val in A, if its smallest pairt in B at pos j is pop off, its next smallest pair is at pos j+1 
                    (3) in the beginning, use smallest val in B to get k pairs in A 
        1. take smallest in A as start, get k pairs in B, push into PQ 
        2. each time pop one pair, update res, update cnt, increment index in B (if within boundry), push bach to pq 
        3. stop when eighter count reaches k or pq is empty already 
        """
        res = [] 
        pq = [] # (pair_sum, i_A, j_B)
        j = 0 
        max_level = min(k,len(A)) # within valid range, put into heap no more than k  
        for i in range(max_level):
            pair_sum = A[i] + B[j]
            heappush(pq,(pair_sum,i,j))
        
        cnt = 0 
        while cnt < k and len(pq)>0: # not assume there will be an answer (maybe number of pairs  < k )  [1,2] [3] k =3 
            pair_sum,i,j = heappop(pq)
            res.append([A[i],B[j]])
            cnt += 1 
            if j+1 == len(B):
                continue 
            j += 1 
            heappush(pq,(A[i]+B[j],i,j))
            
        return res