56. 合并区间

以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。

引言---之前写这道题的思路第一思路是想到用栈来保存一个区间,然后和后续的区间进行对比分情况讨论,但是之前一直没有AC,现在终于完成了,于是记录在这里了。

解题思路

要解决这个问题,我们可以按照以下步骤进行:

  1. 排序:首先将所有区间按照起始时间进行排序。这样我们可以确保在遍历时,相邻的区间是有序的,便于合并。

  2. 合并:使用一个栈来辅助合并区间。遍历排序后的区间列表,如果当前区间与栈顶的区间有重叠,则合并它们;否则,将当前区间压入栈中。

  3. 输出结果:最后,栈中剩余的区间就是合并后的结果。

    class Solution {
    public:
        vector<vector<int>> merge(vector<vector<int>>& intervals) {
            vector<vector<int>> ret;
            stack<int> st;
            // 对区间按起始时间排序
            sort(intervals.begin(), intervals.end());
            for (auto e : intervals) {
                if (st.empty()) {
                    st.push(e[0]);
                    st.push(e[1]);
                } else if (e[0] <= st.top()) {
                    int tem = st.top();
                    st.pop();
                    st.push(max(e[1], tem));
                } else {
                    int x = st.top();
                    st.pop();
                    int y = st.top();
                    st.pop();
                    ret.push_back({y, x});
                    st.push(e[0]);
                    st.push(e[1]);
                }
            }
            //最后剩下的区间
            int x = st.top();
            st.pop();
            int y = st.top();
            st.pop();
            ret.push_back({y, x});
            return ret;
        }
    };

    代码解析

  4. 排序:我们使用sort函数对区间进行排序,确保所有区间按起始时间升序排列。

  5. 栈的使用:我们使用一个栈来存储当前合并后的区间。栈中存储的是区间的起始和结束时间。

  6. 合并逻辑

    • 如果栈为空,直接将当前区间的起始和结束时间压入栈中。

    • 如果当前区间的起始时间小于等于栈顶的结束时间,说明有重叠,我们更新栈顶的结束时间为当前区间和栈顶区间的最大结束时间。因为我们前面排序仅仅排序了开始时间我们并不知道哪个区间的结束时间更晚!!!!

    • 如果没有重叠,我们将栈中的区间弹出并存入结果集,然后将当前区间压入栈中。

  7. 处理剩余区间:最后,栈中还有剩余的区间,将其弹出并存入结果集。

  8. 复杂度分析

  9. 时间复杂度:排序的时间复杂度为O(n log n),遍历区间的时间复杂度为O(n),因此总的时间复杂度为O(n log n)。

  10. 空间复杂度:我们使用了一个栈来存储区间,最坏情况下栈的大小为O(n),因此空间复杂度为O(n)。

    总结

    通过排序和栈的结合使用,我们可以高效地解决合并区间的问题。这个方法不仅思路清晰,而且代码实现也相对简洁。希望本文能帮助你更好地理解这个问题及其解决方案。如果你有任何问题或建议,欢迎在评论区留言讨论。

好的,我很乐意为您解释力扣56题"合并区间"的Python解法。 力扣56题"合并区间"是一个经典的区间问题。题目要求我们将一个包含多个重叠区间的列表合并成不重叠的区间列表。 以下是一个Python解法: ```python class Solution: def merge(self, intervals: List[List[int]]) -> List[List[int]]: # 首先按区间的起始位置排序 intervals.sort(key=lambda x: x[0]) merged = [] for interval in intervals: # 如果当前区间与结果列表中的最后一个区间不重叠,直接添加 if not merged or merged[-1][1] < interval[0]: merged.append(interval) else: # 否则,有重叠,更新结果列表中最后一个区间的结束位置 merged[-1][1] = max(merged[-1][1], interval[1]) return merged ``` 这个解法的主要步骤如下: 1. 首先,我们按每个区间的起始位置对输入的区间列表进行排序。 2. 然后,我们初始化一个空的合并结果列表。 3. 我们遍历排序后的区间列表: - 如果当前区间与结果列表中的最后一个区间不重叠,我们就直接将当前区间添加到结果列表中。 - 如果有重叠,我们就更新结果列表中最后一个区间的结束位置为当前区间和原最后一个区间结束位置的最大值。 4. 最后,我们返回合并后的结果列表。 这个算法的时间复杂度是O(n log n),其中n是区间的数量,主要是因为我们进行了排序操作。空间复杂度是O(n),用于存储结果。 这个解法的高效之处在于通过排序简化了重叠区间的判断过程,使得我们只需要比较结果列表中的最后一个区间和当前区间就可以决定如何处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值