代码随想录|Day30|贪心05|435.无重叠区间、763.划分字母的区间、56.合并区间

本文介绍了三种与区间操作相关的算法问题,包括如何用最少箭矢合并重叠区间、划分包含所有字符的最小区间,以及处理类似452和435问题的贪心策略。通过排序和比较边界值,有效地减少了区间数量和复杂度。
摘要由CSDN通过智能技术生成

435.无重叠区间

本题与 452.用最少数量的箭引爆气球 的思路类似:若按左边界排序,如果当前区间的 左边界 < 前一区间的 右边界,则说明重叠。此时我们有两种移除选择:

  1. 移除前一个区间,或者
  2. 移除当前区间

我们使用贪心策略:为了最小化总体上需要移除的区间数量,我们选择保留结束较早的区间(即右边界较小的区间),因为它留给后续区间的潜在重叠空间更小。

class Solution:
    def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:

        intervals.sort(key=lambda x: x[0])  # 按照左边界升序排序
        
        count = 0

        for i in range(1, len(intervals)):
            # 当前区间的 左边界 < 上一区间的 右边界
            # 说明区间重叠
            if intervals[i][0] < intervals[i-1][1]:
                count += 1
                intervals[i][1] = min(intervals[i][1], intervals[i-1][1])
        return count

763.划分字母的区间

1. 记录每个字符的最后出现位置

算法首先遍历整个字符串,为每个字符记录下它在字符串中最后一次出现的索引位置。这一步是关键,因为要确保一个片段包含了其所有字符的所有出现,这个片段就必须延伸到每个字符的最后出现位置。

2. 确定片段边界

接下来,算法再次遍历字符串,这次是为了确定片段的边界。这通过以下方式完成:

  • 为每个正在考察的字符,确定它的最后出现位置(使用之前记录的信息)。
  • 使用一个变量end来跟踪当前片段的潜在结束位置。对于每个新字符,如果它的最后出现位置比当前的end大,就更新end为这个更大的值。这确保了当前片段能包含目前所有已遍历字符的最后出现。
  • 当遍历到的位置i等于end时,说明找到了一个片段的边界。此时,可以从startend的这一段字符串切分出来作为一个独立的片段,因为它包含了这个范围内所有字符的所有出现,且不会与下一个片段重复。

3. 更新并记录片段长度

每当找到一个片段的边界时,计算这个片段的长度(end - start + 1),并将这个长度加入到最终结果的列表中。随后,更新startend + 1,即下一个片段的起始位置,继续寻找下一个片段直到字符串结束。

class Solution:
    def partitionLabels(self, s: str) -> List[int]:

        record = {}
        res = []

        for index, char in enumerate(s):
            record[char] = index

        end, start = 0, 0
        
        for index, char in enumerate(s):

            end = max(end, record[char])
            # 说明一个符合条件的区间遍历完成
            if index == end:
                res.append(end - start + 1)
                start = end + 1
        return res

56.合并区间

思路与  452.用最少数量的箭引爆气球 和 435.无重叠区间 类似:遍历排序后的区间列表,对每个区间,判断它是否与前一个区间重叠。如果不重叠,就直接将当前区间添加到结果列表中。如果重叠,就将前一个区间的结束位置更新为当前区间结束位置和前一个区间结束位置的较大值,从而合并这两个区间。

class Solution:
    def merge(self, intervals: List[List[int]]) -> List[List[int]]:

        intervals.sort(key = lambda x: x[0])
        res = []
        # 需要将第一个区间放入,以便后续合并或加入区间
        res.append(intervals[0])

        for i in range(1, len(intervals)):
            # 注意区间紧挨也要合并
            if res[-1][1] >= intervals[i][0]:
                res[-1][1] = max(res[-1][1], intervals[i][1])
            else:
                res.append(intervals[i])
        return res
  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值