秋招算法备战第36天 | 435. 无重叠区间、763.划分字母区间、56. 合并区间

435. 无重叠区间 - 力扣(LeetCode)

这个问题可以通过贪心算法来解决。首先,我们将区间按照结束时间进行升序排序,然后我们可以从左到右遍历区间,选择结束时间最早的区间,并从集合中移除所有与该区间重叠的其它区间。重复此过程,直到集合为空。

以下是一个可能的实现:

python 复制代码
def eraseOverlapIntervals(intervals):
    if not intervals:
        return 0

    # 按照结束时间进行升序排序
    intervals.sort(key=lambda x: x[1])

    # 初始化计数器和第一个区间的结束时间
    count = 0
    end_time = intervals[0][1]

    # 从第二个区间开始遍历
    for i in range(1, len(intervals)):
        # 如果区间的开始时间小于上一个区间的结束时间,说明有重叠
        if intervals[i][0] < end_time:
            count += 1
        else:
            # 如果没有重叠,更新结束时间
            end_time = intervals[i][1]

    return count

intervals1 = [[1,2],[2,3],[3,4],[1,3]]
intervals2 = [[1,2],[1,2],[1,2]]
intervals3 = [[1,2],[2,3]]
print(eraseOverlapIntervals(intervals1))  # 输出: 1
print(eraseOverlapIntervals(intervals2))  # 输出: 2
print(eraseOverlapIntervals(intervals3))  # 输出: 0

这个实现的时间复杂度为O(n log n),其中n为区间的数量。排序占用了主要的时间复杂度。空间复杂度为O(1),只使用了常数额外空间。

763. 划分字母区间 - 力扣(LeetCode)

这个问题可以通过贪心算法来解决。我们可以先遍历一遍字符串,找出每个字母的最后一次出现的位置。然后再次遍历字符串,根据每个字母的最后一次出现的位置,来确定每个片段的范围。

以下是一个可能的实现:

python 复制代码
def partitionLabels(s):
    # 记录每个字母最后一次出现的位置
    last_occurrence = {char: index for index, char in enumerate(s)}
    
    result = []
    start = 0
    end = 0
    
    # 再次遍历字符串
    for index, char in enumerate(s):
        # 更新片段的结束位置
        end = max(end, last_occurrence[char])
        
        # 如果达到片段的结束位置,则记录片段长度,并更新下一个片段的开始位置
        if index == end:
            result.append(end - start + 1)
            start = index + 1
            
    return result

s1 = "ababcbacadefegdehijhklij"
s2 = "eccbbbbdec"
print(partitionLabels(s1))  # 输出: [9,7,8]
print(partitionLabels(s2))  # 输出: [10]

这个实现的时间复杂度为O(n),其中n为字符串的长度。我们只需要两次遍历字符串。空间复杂度也为O(n),用于存储每个字母的最后一次出现的位置。

56. 合并区间 - 力扣(LeetCode)

合并重叠区间的问题可以通过先按照每个区间的开始时间排序,然后遍历区间来解决。

以下是一个可能的实现:

python 复制代码
def merge(intervals):
    # 如果区间为空或只有一个区间,直接返回
    if len(intervals) <= 1:
        return intervals
    
    # 按照开始时间进行升序排序
    intervals.sort(key=lambda x: x[0])
    
    result = []
    current_interval = intervals[0]
    
    # 遍历排序后的区间
    for i in range(1, len(intervals)):
        # 如果下一个区间的开始时间小于或等于当前区间的结束时间,说明有重叠,合并它们
        if intervals[i][0] <= current_interval[1]:
            current_interval[1] = max(current_interval[1], intervals[i][1])
        else:
            # 如果没有重叠,添加当前区间到结果,并更新当前区间
            result.append(current_interval)
            current_interval = intervals[i]
            
    # 将最后一个区间添加到结果
    result.append(current_interval)
    
    return result

intervals1 = [[1,3],[2,6],[8,10],[15,18]]
intervals2 = [[1,4],[4,5]]
print(merge(intervals1))  # 输出: [[1,6],[8,10],[15,18]]
print(merge(intervals2))  # 输出: [[1,5]]

这个实现的时间复杂度为O(n log n),其中n为区间的数量。排序占用了主要的时间复杂度。空间复杂度为O(1),只使用了常数额外空间。

总结(详细版)

1. 无重叠区间(435)

问题描述:给定一个区间集合,返回需要移除区间的最小数量,使剩余区间互不重叠。

解决方案:通过贪心算法实现,按结束时间排序,然后遍历区间,选择结束时间最早的区间,移除所有与该区间重叠的其他区间。

时间复杂度 :O(n log n),排序占主要时间。
空间复杂度:O(1)。

2. 划分字母区间(763)

问题描述:给定一个字符串,将其划分为尽可能多的片段,使同一字母最多出现在一个片段中。

解决方案:先遍历一遍字符串,找出每个字母的最后一次出现的位置。然后再次遍历,根据每个字母的最后一次出现的位置来确定每个片段的范围。

时间复杂度 :O(n),遍历字符串两次。
空间复杂度:O(n),存储每个字母的最后一次出现位置。

3. 合并区间(56)

问题描述:给定若干个区间的集合,合并所有重叠的区间,返回一个不重叠的区间数组。

解决方案:按照每个区间的开始时间排序,然后遍历区间,合并重叠的区间。

时间复杂度 :O(n log n),排序占主要时间。
空间复杂度:O(1)。

总结

这三个问题虽然都涉及到区间操作,但其解决方案分别使用了贪心、遍历和排序的组合。它们展示了如何通过对问题进行分析,选择合适的算法设计技术(例如贪心策略或排序)来高效解决问题。通过合理的策略选择,我们可以在不同的场景下达到最优或近似最优的解决方案。

总结(简洁版)

下面是对上述三个问题最重点、最核心部分的对比总结:

1. 无重叠区间(435)

核心:贪心选择结束时间最早的区间,并移除所有与之重叠的区间。

2. 划分字母区间(763)

核心:记录每个字母的最后出现位置,以此确定不重叠的片段范围。

3. 合并区间(56)

核心:排序并遍历区间,合并所有重叠的区间。

对比总结

  • 贪心 vs 遍历 vs 排序

    • 无重叠区间问题通过贪心选择获得最优解。
    • 划分字母区间问题通过两次遍历确定划分。
    • 合并区间问题通过排序和遍历完成合并。
  • 处理对象的差异

    • 无重叠区间和合并区间问题都涉及到区间的操作,但一个是移除重叠,一个是合并重叠。
    • 划分字母区间则处理的是字符串,与其他两题的区间操作有所不同。
  • 解决策略的差异

    • 无重叠区间问题强调的是选择,通过选择特定区间达到解决问题的目的。
    • 划分字母区间问题强调的是统计和划分,通过分析字符出现的位置实现划分。
    • 合并区间问题强调的是排序和合并,通过排序来简化合并过程。

这三个问题虽然都涉及到了区间或者划分,但其解决的核心机制存在明显差异,反映了算法设计中的多样性和灵活性。不同的问题结构和要求导致了解决方案上的重点和核心部分有所不同。

相关推荐
Ven%18 小时前
【AI大模型算法工程师面试题解析与技术思考】
人工智能·python·算法
天勤量化大唯粉18 小时前
枢轴点反转策略在铜期货中的量化应用指南(附天勤量化代码)
ide·python·算法·机器学习·github·开源软件·程序员创富
爱学习的小仙女!18 小时前
算法效率的度量 时间复杂度 空间复杂度
数据结构·算法
AndrewHZ18 小时前
【复杂网络分析】什么是图神经网络?
人工智能·深度学习·神经网络·算法·图神经网络·复杂网络
Swizard18 小时前
拒绝“狗熊掰棒子”!用 EWC (Elastic Weight Consolidation) 彻底终结 AI 的灾难性遗忘
python·算法·ai·训练
fab 在逃TDPIE19 小时前
Sentaurus TCAD 仿真教程(十)
算法
天赐学c语言19 小时前
12.19 - 买卖股票的最佳时机 && const的作用
c++·算法·leecode
菜鸟233号19 小时前
力扣78 子集 java实现
java·数据结构·算法·leetcode
yesyesyoucan20 小时前
在线魔方解谜站:从零入门到精通的智能魔方学习平台
学习·算法
Han.miracle20 小时前
数据结构与算法--008四数之和 与经典子数组 / 子串问题解析
数据结构·算法