LeetCode //C - 632. Smallest Range Covering Elements from K Lists

632. Smallest Range Covering Elements from K Lists

You have k lists of sorted integers in non-decreasing order. Find the smallest range that includes at least one number from each of the k lists.

We define the range [a, b] is smaller than range [c, d] if b - a < d - c or a < c if b - a == d - c.
 

Example 1:

Input: nums = [[4,10,15,24,26],[0,9,12,20],[5,18,22,30]]
Output: [20,24]
Explanation:
List 1: [4, 10, 15, 24,26], 24 is in range [20,24].
List 2: [0, 9, 12, 20], 20 is in range [20,24].
List 3: [5, 18, 22, 30], 22 is in range [20,24].

Example 2:

Input: nums = [[1,2,3],[1,2,3],[1,2,3]]
Output: [1,1]

Constraints:
  • nums.length == k
  • 1 <= k <= 3500
  • 1 <= nums[i].length <= 50
  • − 1 0 5 < = n u m s [ i ] [ j ] < = 1 0 5 -10^5 <= nums[i][j] <= 10^5 105<=nums[i][j]<=105
  • nums[i] is sorted in non-decreasing order.

From: LeetCode
Link: 632. Smallest Range Covering Elements from K Lists


Solution:

Ideas:
  • Use a Min-Heap (Priority Queue): Keeps track of the smallest element across the k lists.
  • Track Maximum Element: Maintains the largest value in the current range.
  • Heap Operations (O(log k)):
    • Push: Insert the next element from the same list.
    • Pop: Remove the smallest element and update the range.
  • Stop Early: If any list is exhausted, we stop (ensuring all k lists are covered).
  • Time Complexity: O(N log k) (N = total elements, k = number of lists).
  • Efficient Heapify: Uses a binary heap instead of qsort() for faster heap operations.
  • Result: Finds the smallest range covering at least one number from each list.
Code:
/* Structure for min-heap nodes */
typedef struct {
    int value;
    int row;
    int col;
} HeapNode;

/* Min-heap functions */
void swap(HeapNode *a, HeapNode *b) {
    HeapNode temp = *a;
    *a = *b;
    *b = temp;
}

void heapify(HeapNode heap[], int size, int i) {
    int smallest = i;
    int left = 2 * i + 1;
    int right = 2 * i + 2;

    if (left < size && heap[left].value < heap[smallest].value)
        smallest = left;
    if (right < size && heap[right].value < heap[smallest].value)
        smallest = right;

    if (smallest != i) {
        swap(&heap[i], &heap[smallest]);
        heapify(heap, size, smallest);
    }
}

void heapPush(HeapNode heap[], int *size, HeapNode node) {
    int i = (*size)++;
    heap[i] = node;

    while (i > 0 && heap[i].value < heap[(i - 1) / 2].value) {
        swap(&heap[i], &heap[(i - 1) / 2]);
        i = (i - 1) / 2;
    }
}

HeapNode heapPop(HeapNode heap[], int *size) {
    HeapNode minNode = heap[0];
    heap[0] = heap[--(*size)];
    heapify(heap, *size, 0);
    return minNode;
}

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* smallestRange(int** nums, int numsSize, int* numsColSize, int* returnSize) {
    int *result = (int*)malloc(2 * sizeof(int));
    int rangeStart = 0, rangeEnd = INT_MAX;
    
    /* Create min-heap */
    HeapNode *heap = (HeapNode*)malloc(numsSize * sizeof(HeapNode));
    int heapSize = 0;
    
    /* Track max value in heap */
    int maxVal = INT_MIN;
    
    /* Initialize heap with the first element of each list */
    for (int i = 0; i < numsSize; i++) {
        heap[heapSize].value = nums[i][0];
        heap[heapSize].row = i;
        heap[heapSize].col = 0;
        maxVal = (maxVal > nums[i][0]) ? maxVal : nums[i][0];
        heapSize++;
    }

    /* Heapify */
    for (int i = heapSize / 2 - 1; i >= 0; i--)
        heapify(heap, heapSize, i);
    
    /* Main loop to find the smallest range */
    while (1) {
        HeapNode minNode = heapPop(heap, &heapSize);
        int minVal = minNode.value;
        
        /* Update range if the current range is smaller */
        if ((maxVal - minVal) < (rangeEnd - rangeStart)) {
            rangeStart = minVal;
            rangeEnd = maxVal;
        }
        
        /* Move to the next element in the same list */
        int nextCol = minNode.col + 1;
        if (nextCol < numsColSize[minNode.row]) {
            HeapNode nextNode;
            nextNode.value = nums[minNode.row][nextCol];
            nextNode.row = minNode.row;
            nextNode.col = nextCol;
            maxVal = (maxVal > nextNode.value) ? maxVal : nextNode.value;
            heapPush(heap, &heapSize, nextNode);
        } else {
            break;  // Stop if we reach the end of one list
        }
    }
    
    /* Set result and return */
    result[0] = rangeStart;
    result[1] = rangeEnd;
    *returnSize = 2;
    
    free(heap);
    return result;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Navigator_Z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值