LeetCode //C - 352. Data Stream as Disjoint Intervals

352. Data Stream as Disjoint Intervals

Given a data stream input of non-negative integers a 1 , a 2 , . . . , a n a_1, a_2, ..., a_n a1,a2,...,an, summarize the numbers seen so far as a list of disjoint intervals.

Implement the SummaryRanges class:

  • SummaryRanges() Initializes the object with an empty stream.
  • void addNum(int value) Adds the integer value to the stream.
  • int[][] getIntervals() Returns a summary of the integers in the stream currently as a list of disjoint intervals [ s t a r t i , e n d i ] [start_i, end_i] [starti,endi]. The answer should be sorted by s t a r t i start_i starti.
Example 1:

Input:

"SummaryRanges", "addNum", "getIntervals", "addNum", "getIntervals", "addNum", "getIntervals", "addNum", "getIntervals", "addNum", "getIntervals"

\[\], \[1\], \[\], \[3\], \[\], \[7\], \[\], \[2\], \[\], \[6\], \[\]

Output:

null, null, \[\[1, 1\]\], null, \[\[1, 1\], \[3, 3\]\], null, \[\[1, 1\], \[3, 3\], \[7, 7\]\], null, \[\[1, 3\], \[7, 7\]\], null, \[\[1, 3\], \[6, 7\]\]

Explanation

SummaryRanges summaryRanges = new SummaryRanges();

summaryRanges.addNum(1); // arr = [1]

summaryRanges.getIntervals(); // return [[1, 1]]

summaryRanges.addNum(3); // arr = [1, 3]

summaryRanges.getIntervals(); // return [[1, 1], [3, 3]]

summaryRanges.addNum(7); // arr = [1, 3, 7]

summaryRanges.getIntervals(); // return [[1, 1], [3, 3], [7, 7]]

summaryRanges.addNum(2); // arr = [1, 2, 3, 7]

summaryRanges.getIntervals(); // return [[1, 3], [7, 7]]

summaryRanges.addNum(6); // arr = [1, 2, 3, 6, 7]

summaryRanges.getIntervals(); // return [[1, 3], [6, 7]]

Constraints:
  • 0 < = v a l u e < = 1 0 4 0 <= value <= 10^4 0<=value<=104
  • At most 3 ∗ 1 0 4 3 * 10^4 3∗104 calls will be made to addNum and getIntervals.
  • At most 1 0 2 10^2 102 calls will be made to getIntervals.

From: LeetCode

Link: 352. Data Stream as Disjoint Intervals


Solution:

Ideas:

1. Intervals Representation:

  • Intervals are stored in a 2D array intervals, where each interval is represented as a pair [start, end].
  • For example, the intervals for numbers [1, 3, 7] would be stored as [[1, 1], [3, 3], [7, 7]].

2. Efficient Insertion:

  • When a new number is added, the code finds the appropriate place to insert it. The intervals are maintained in sorted order, so the number is compared to the existing intervals.
  • Depending on whether the new number is adjacent to an existing interval, it either extends or merges the intervals.

3. Merging Logic:

  • Merge with the previous interval: If the new number is just after the previous interval (i.e., new number == previous interval end + 1), then the previous interval is extended.
  • Merge with the next interval: If the new number is just before the next interval (i.e., new number == next interval start - 1), then the next interval is extended.
  • Merge both previous and next intervals: If the new number is adjacent to both the previous and the next intervals, the two intervals are merged into one.
  • New Interval: If the new number is not adjacent to any existing intervals, a new interval is created.

4. Dynamic Array Management:

  • The intervals array has an initial capacity, and when it fills up, it is dynamically resized to accommodate more intervals. This ensures that the solution can handle up to the maximum number of intervals allowed by the problem constraints.
Code:
c 复制代码
typedef struct {
    int** intervals;   // To store the intervals as a 2D array
    int size;          // The current number of intervals
    int capacity;      // The allocated capacity of the intervals array
} SummaryRanges;

SummaryRanges* summaryRangesCreate() {
    SummaryRanges* obj = (SummaryRanges*)malloc(sizeof(SummaryRanges));
    obj->size = 0;
    obj->capacity = 10; // Initial capacity
    obj->intervals = (int**)malloc(sizeof(int*) * obj->capacity);
    for (int i = 0; i < obj->capacity; ++i) {
        obj->intervals[i] = (int*)malloc(sizeof(int) * 2); // Each interval has two elements [start, end]
    }
    return obj;
}

void summaryRangesAddNum(SummaryRanges* obj, int value) {
    int i = 0;
    
    // Find the position to insert or merge intervals
    while (i < obj->size && obj->intervals[i][1] < value) {
        i++;
    }
    
    // Check if value is already included in an interval
    if (i < obj->size && obj->intervals[i][0] <= value && obj->intervals[i][1] >= value) {
        return;
    }

    // Merge with the previous and next intervals if possible
    int mergeWithPrev = (i > 0 && obj->intervals[i - 1][1] + 1 == value);
    int mergeWithNext = (i < obj->size && obj->intervals[i][0] - 1 == value);

    if (mergeWithPrev && mergeWithNext) {
        // Merge both previous and next intervals
        obj->intervals[i - 1][1] = obj->intervals[i][1];
        // Remove the current interval
        for (int j = i; j < obj->size - 1; ++j) {
            obj->intervals[j][0] = obj->intervals[j + 1][0];
            obj->intervals[j][1] = obj->intervals[j + 1][1];
        }
        obj->size--;
    } else if (mergeWithPrev) {
        // Merge with the previous interval
        obj->intervals[i - 1][1] = value;
    } else if (mergeWithNext) {
        // Merge with the next interval
        obj->intervals[i][0] = value;
    } else {
        // Insert a new interval
        if (obj->size == obj->capacity) {
            obj->capacity *= 2;
            obj->intervals = (int**)realloc(obj->intervals, sizeof(int*) * obj->capacity);
            for (int j = obj->size; j < obj->capacity; ++j) {
                obj->intervals[j] = (int*)malloc(sizeof(int) * 2);
            }
        }
        for (int j = obj->size; j > i; --j) {
            obj->intervals[j][0] = obj->intervals[j - 1][0];
            obj->intervals[j][1] = obj->intervals[j - 1][1];
        }
        obj->intervals[i][0] = value;
        obj->intervals[i][1] = value;
        obj->size++;
    }
}

int** summaryRangesGetIntervals(SummaryRanges* obj, int* retSize, int** retColSize) {
    *retSize = obj->size;
    *retColSize = (int*)malloc(sizeof(int) * obj->size);
    for (int i = 0; i < obj->size; ++i) {
        (*retColSize)[i] = 2; // Each interval has two columns
    }
    return obj->intervals;
}

void summaryRangesFree(SummaryRanges* obj) {
    for (int i = 0; i < obj->capacity; ++i) {
        free(obj->intervals[i]);
    }
    free(obj->intervals);
    free(obj);
}

/**
 * Your SummaryRanges struct will be instantiated and called as such:
 * SummaryRanges* obj = summaryRangesCreate();
 * summaryRangesAddNum(obj, value);
 * int** param_2 = summaryRangesGetIntervals(obj, retSize, retColSize);
 * summaryRangesFree(obj);
 */
相关推荐
CoovallyAIHub17 小时前
181小时视频丢给GPT-5,准确率只有15%——南大联合NVIDIA等五校发布多模态终身理解数据集
深度学习·算法·计算机视觉
CoovallyAIHub17 小时前
CVPR 2026 | GS-CLIP:3D几何先验+双流视觉融合,零样本工业缺陷检测新SOTA,四大3D工业数据集全面领先!
深度学习·算法·计算机视觉
xlp666hub17 小时前
Leetcode 第三题:用C++解决最长连续序列
c++·leetcode
有意义20 小时前
深度拆解分割等和子集:一维DP数组与倒序遍历的本质
前端·算法·面试
xlp666hub21 小时前
Leetcode第二题:用 C++ 解决字母异位词分组
c++·leetcode
用户7268761033721 小时前
解放双手的健身助手:基于 Rokid AR 眼镜的运动计时应用
算法
Wect21 小时前
LeetCode 17. 电话号码的字母组合:回溯算法入门实战
前端·算法·typescript
xlp666hub2 天前
Leetcode第一题:用C++解决两数之和问题
c++·leetcode
ZhengEnCi2 天前
08c. 检索算法与策略-混合检索
后端·python·算法