代码随想录 贪心Ⅴ

435. 无重叠区间

给定一个区间的集合 intervals ,其中 intervals[i] = [starti, endi] 。返回 需要移除区间的最小数量,使剩余区间互不重叠 

思路:跟打爆气球类似,将区间看作是气球的位置就行。不同的地方在于:需要先给区间排序,并且区间的边界重合不算是重叠。

class Solution:
    def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
        if not intervals:
            return 0
        
        intervals.sort(key=lambda x:x[0])
        
        arrow = 1
        min_right = intervals[0][1]
        for i in intervals[1:]:
            if i[0] >= min_right:
                arrow += 1
                min_right = i[1]
            else:
                min_right = min(i[1], min_right)
            
        return len(intervals) - arrow

 763. 划分字母区间

给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。

注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s 。

返回一个表示每个字符串片段的长度的列表。

思路:首先记录每一个字母的最远位置,然后从左往右遍历,遍历的同时维护一个当前最远距离,表示在该位置之前的字母对应的最远距离。如果遍历的位置恰好为最远距离,则说明该位置为在这之前的所有字母的最远距离的最大值,在这里可以划分一个区间,将区间长度放到answer列表中去。

class Solution:
    def partitionLabels(self, s: str) -> List[int]:
        last_occurrence = {}  # 存储每个字符母最后出现的位置
        for i, ch in enumerate(s):
            last_occurrence[ch] = i

        ans = []
        start = 0
        end = 0
        for i, ch in enumerate(s):
            end = max(end, last_occurrence[ch])  # 找到当前字母出现的最远位置
            if i == end:  # 如果当前位置是最远位置,表示可以分割出一个区间
                ans.append(end - start + 1)
                start = i + 1

        return ans

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] 可被视为重叠区间。
  • 注意:输入类型已于2019年4月15日更改。 请重置默认代码定义以获取新方法签名。

思路:跟打气球一样,属于区间重叠问题,排序后遍历,维护一个当前重叠区间,如果区间不与当前重叠区间有重叠,则将重叠区间添加到answer列表中,然后更新该区间为新的重叠区间。

Python:

class Solution:
    def merge(self, intervals: List[List[int]]) -> List[List[int]]:
        ans = []
        if not intervals:
            return ans
        
        intervals.sort(key= lambda x:x[0])

        cache = intervals[0]
        for i in intervals:
            # 如果该区间与大区间有重叠,则更新大区间
            if i[0] <= cache[1]:
                cache[1] = max(i[1], cache[1])

            else:
                ans.append(cache)
                cache = i
        ans.append(cache)  # 遍历到最后时,把最后一个大区间加入到answer列表中
        return ans

你可能感兴趣的:(算法)