DAY35 435. 无重叠区间 + 763.划分字母区间 + 56. 合并区间

435. 无重叠区间

题目要求:给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。

注意: 可以认为区间的终点总是大于它的起点。 区间 [1,2] 和 [2,3] 的边界相互"接触",但没有相互重叠。

示例 1:

  • 输入: [ [1,2], [2,3], [3,4], [1,3] ]
  • 输出: 1
  • 解释: 移除 [1,3] 后,剩下的区间没有重叠。

示例 2:

  • 输入: [ [1,2], [1,2], [1,2] ]
  • 输出: 2
  • 解释: 你需要移除两个 [1,2] 来使剩下的区间没有重叠。

示例 3:

  • 输入: [ [1,2], [2,3] ]
  • 输出: 0
  • 解释: 你不需要移除任何区间,因为它们已经是无重叠的了。

思路

按照右边界排序,从左向右记录非交叉区间的个数。最后用总区间数减去非交叉区间的个数就是需要移除的区间的个数。

核心:把所有规则下有重叠的区间当作是一个区间来考虑。

cpp 复制代码
class Solution {
public:
    static bool cmp(const vector<int>& a, const vector<int>& b) {
        return a[1] < b[1];
    }
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
        if (intervals.size() == 0) return 0;
        sort(intervals.begin(), intervals.end(), cmp);
        int count = 1;
        int end = intervals[0][1];
        for (int i = 1; i < intervals.size(); ++i) {
            if (end <= intervals[i][0]) {
                end = intervals[i][1];
                count++;
            }
        }
        return intervals.size() - count;
    }
};

763.划分字母区间

字符串 S 由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。返回一个表示每个字符串片段的长度的列表。

示例:

  • 输入:S = "ababcbacadefegdehijhklij"
  • 输出:[9,7,8] 解释: 划分结果为 "ababcbaca", "defegde", "hijhklij"。 每个字母最多出现在一个片段中。 像 "ababcbacadefegde", "hijhklij" 的划分是错误的,因为划分的片段数较少。

提示:

  • S的长度在[1, 500]之间。
  • S只包含小写字母 'a' 到 'z' 。

思路

在遍历的过程中相当于是要找每一个字母的边界,如果找到之前遍历过的所有字母的最远边界,说明这个边界就是分割点了。此时前面出现过所有字母,最远也就到这个边界了。

  • 统计每一个字符最后出现的位置
  • 从头遍历字符,并更新字符的最远出现下标,如果找到字符最远出现位置下标和当前下标相等了,则找到了分割点
cpp 复制代码
class Solution {
public:
    vector<int> partitionLabels(string s) {
        int hash[27] = {0};
        for (int i = 0; i < s.size(); ++i) {
            hash[s[i] - 'a'] = i; // 更新每个字符出现的最后位置
        }
        vector<int> result;
        int left = 0;
        int right = 0;
        for (int i = 0; i < s.size(); ++i) {
            right = max(right, hash[s[i] - 'a']); // 找到字符出现的最远边界
            if (i == right) {
                result.push_back(right - left + 1);
                left = i + 1;
            }
        }
        return result;
    }
};

56. 合并区间

题目要求:给出一个区间的集合,请合并所有重叠的区间。

示例 1:

  • 输入: intervals = [[1,3],[2,6],[8,10],[15,18]]
  • 输出: [[1,6],[8,10],[15,18]]
  • 解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].

示例 2:

  • 输入: intervals = [[1,4],[4,5]]
  • 输出: [[1,5]]
  • 解释: 区间 [1,4] 和 [4,5] 可被视为重叠区间。

思路

首先需要先按照左边界排序。先判断重叠,然后不断更新重叠的左右边界,当遇到不重叠时计入res数组。

按照左边界排序可以保证最小的左边界在前,可以直接把第一个左边界push进结果数组,在更新时也只需要对重叠进行判断而不需要判断左边界的关系。

cpp 复制代码
class Solution {
public:
    static bool cmp(const vector<int>& a, const vector<int>& b) {
        return a[0] < b[0];
    }
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        vector<vector<int>> result;
        if (intervals.size() == 0) return result;
        sort(intervals.begin(), intervals.end(), cmp);
        result.push_back(intervals[0]);
        for (int i = 1; i < intervals.size(); ++i) {
            if (result.back()[1] >= intervals[i][0]) {
                result.back()[1] = max(result.back()[1], intervals[i][1]);
            } else {
                result.push_back(intervals[i]);
            }
        }
        return result;
    }
};
  • 时间复杂度: O(nlogn)
  • 空间复杂度: O(logn),排序需要的空间开销

/ec = 该C++代码片段是用于合并区间的。主要有以下几个部分需要考虑时间复杂度:

  1. `sort(intervals.begin(), intervals.end(), cmp);`:这一行代码的时间复杂度是O(n log n),其中n是区间的数量。这里使用了标准库的排序算法。

  2. 循环 `for (int i = 1; i < intervals.size(); ++i)`:这一行代码开始的循环有O(n)的时间复杂度。在循环内部,所有操作(包括vector的push_back和max函数)都是O(1)的时间复杂度。

因此,总体时间复杂度是O(n log n) + O(n) = O(n log n)。

所以,这个代码的时间复杂度是O(n log n)。

相关推荐
杨连江3 分钟前
原子级平面限域协同晶核诱导定向生长单层鳞片石墨的研究
算法
MATLAB代码顾问9 分钟前
混合粒子群-模拟退火算法(HPSO-SA)求解作业车间调度问题——附MATLAB代码
算法·matlab·模拟退火算法
Felven13 分钟前
C. Prefix Min and Suffix Max
算法
加农炮手Jinx14 分钟前
LeetCode 26. Remove Duplicates from Sorted Array 题解
算法·leetcode·力扣
加农炮手Jinx14 分钟前
LeetCode 88. Merge Sorted Array 题解
算法·leetcode·力扣
格林威14 分钟前
线阵工业相机:如何计算线阵相机的行频(Line Rate)?公式+实例
开发语言·人工智能·数码相机·算法·计算机视觉·工业相机·线阵相机
yueyue54317 分钟前
透过现象看本质:以fast_lio架构的整套算法的局部避障改为TEB算法为例深度探讨——如何成为一个合格的算法架构师?
算法·架构
梨花爱跨境17 分钟前
红人视频×A10算法:亚马逊转化率与流量闭环实战
算法
阿Y加油吧22 分钟前
二刷 LeetCode:75. 颜色分类 & 31. 下一个排列 复盘笔记
笔记·算法·leetcode
风筝在晴天搁浅23 分钟前
LeetCode 378.有序矩阵中第K小的元素
算法·矩阵