435. 无重叠区间
- LeetCode
思路: 本题是一个去除重叠区间的问题, 首先按照区间的 end_point 排序, 从第二个区间开始, 如果第二个区间和第一个区间有交集, 就要移除第二个区间。 因为容易证明之后的区间区间如果和第一个有交集, 必然和第二个有交集, 反之不成立。 如果第一个区间和第二个没有交集, end_point 更新到第二个区间的右端, 继续循环。
难点: 两个区间不相交的时候记得移动右端点
class Solution:def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:intervals.sort(key=lambda x: x[1])ep = intervals[0][1]removes = 0for i in range(1,len(intervals)):if intervals[i][0] < ep:removes += 1ep = min(ep, intervals[i][1])else:ep = intervals[i][1]return removes
763.划分字母区间
- LeetCode
思路:这个问题虽然包了层string 的皮, 但还是区间相交的问题。 首先循环字符串, 对于字符串中的字符记下它存在的区间, 区间的左端点是第一次出现的位置, 右端点是最后一次出现的位置。 例如 "ababcbacadefegdehijhklij" a 的区间就是 [0, 8]. 接下来要做的就是合并区间,先根据开头位置排序(其实第一步已经排好了),然后从第二个开始循环所有区间,如果和上一个区间有交集, 合并的区间右端点更新到两个右端的最大值。 如果没有交易, 上个区间的 end_point - start_point + 1 就是一段分割后的字符串长度。
难点: 把string 问题翻译成区间交集问题。
class Solution:def partitionLabels(self, s: str) -> List[int]:interval_dict = defaultdict(lambda: [0, 0])occurences = set()for i, letter in enumerate(s):if letter in occurences:interval_dict[letter][1] = ielse:occurences.add(letter)interval_dict[letter][0] = i interval_dict[letter][1] = i intervals = list(interval_dict.values())# print(intervals)ans = []cur_sp, cur_ep = intervals[0][0], intervals[0][1]for i in range(1, len(intervals)):if intervals[i][0] < cur_ep:cur_ep = max(cur_ep, intervals[i][1])else:ans.append(cur_ep - cur_sp + 1)cur_sp, cur_ep = intervals[i][0], intervals[i][1]ans.append(cur_ep - cur_sp + 1)return ans
56. 合并区间
- LeetCode
思路: 这不是上一个问题一摸一样嘛。。。
难点: 无
class Solution:def merge(self, intervals: List[List[int]]) -> List[List[int]]:intervals.sort(key = lambda x: x[0])cur_sp, cur_ep = intervals[0][0], intervals[0][1]ans = []for i in range(1, len(intervals)):if intervals[i][0] <= cur_ep:cur_ep = max(cur_ep, intervals[i][1])else:ans.append([cur_sp, cur_ep])cur_sp, cur_ep = intervals[i][0], intervals[i][1]ans.append([cur_sp, cur_ep])return ans