代码随想录算法训练营day36 | 贪心: 435. 无重叠区间,763. 划分字母区间,56. 合并区间

重叠区间题目:

452. 用最少数量的箭引爆气球(medium)

class Solution:
    def findMinArrowShots(self, points: List[List[int]]) -> int:
        if not points:
            return 0
        
        res = 1
        points.sort(key=lambda x: x[0])
        print(points)
        
        for i in range(1, len(points)):
            if points[i][0] > points[i-1][1]:
                res += 1
            else:
                points[i][1] = min(points[i][1], points[i-1][1])
        return res

435. 无重叠区间(medium)

  • https://www.youtube.com/watch?v=nONCGxWoUfM

trick: 题目只是要求移除区间的个数,没有必要去真实的模拟删除区间!

class Solution:
    def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
        intervals.sort() #默认是按照 (key=lambda x: (x[0], x[1]))来排序
        print(intervals)
        
        res = 0
        prevEnd = intervals[0][1]
        for start, end in intervals[1:]:
            if start < prevEnd:
                res += 1
                prevEnd = min(prevEnd, end) # 右边界越小越好,只要右边界越小,留给下一个区间的空间就越大
            else:
                prevEnd = end
        
        return res

763. 划分字母区间(medium)

  • https://www.youtube.com/watch?v=B7m8UmZE-vw

  • 统计每一个字符最后出现的位置
  • 从头遍历字符,并更新字符的最远出现下标,如果找到字符最远出现位置下标和当前下标相等了,则找到了分割点

注意两种hashmap的构成方式

class Solution:
    def partitionLabels(self, s: str) -> List[int]:
        #首先需要hashmap记录字母出现的最远边界
        #1 数组作为hashmap
        temp = [0]*26
        for i in range(len(s)):
            temp[ord(s[i]) - ord('a')] = i
        print(temp)
        
        res = []
        left = 0
        right = 0
        for i in range(len(s)):
            right = max(right, temp[ord(s[i])-ord('a')]) #在hashmap内取值(每个字母出现的最远边界)
            if i == right:
                res.append(right-left+1)
                left = right+1
        return res
            
class Solution(object):
    def partitionLabels(self, s):
        """
        :type s: str
        :rtype: List[int]
        """
        #2 字典作为hashmap
        temp = {}
        for i, c in enumerate(s):
            temp[c] = i
        print(temp)
        
        res = []
        left = 0
        right = 0
        for i, c in enumerate(s):
            right = max(right, temp[c])
            if i == right:
                res.append(right-left+1)
                left = right+1
                
        return res
            
        

56. 合并区间(medium)

  • https://www.youtube.com/watch?v=44H3cEC2fFM

class Solution:
    def merge(self, intervals: List[List[int]]) -> List[List[int]]:
        intervals.sort()
        res = [intervals[0]]
        
        for start, end in intervals[1:]:
            lastEnd = res[-1][1]
            if start <= lastEnd: #overlap
                res[-1][1] = max(res[-1][1], end)
            else:
                res.append([start, end])
                
        return res
        

你可能感兴趣的:(leetcode,算法,数据结构,贪心算法)