● 435. 无重叠区间
● 763.划分字母区间
● 56. 合并区间
1. 无重叠区间
关联 leetcode 435. 无重叠区间
-
思路
- 允许边界值重合
- 区间严格大于
- 逆向思维:
- 删除重叠区间
- 先对区间排序【左右任选】
- 允许边界值重合
-
题解
func eraseOverlapIntervals(intervals [][]int) int { length := len(intervals) if length < 2 { return 0 } // 排序, 左区间升序 sort.Slice(intervals, func(i, j int) bool { return intervals[i][0] < intervals[j][0] }) count := 0 //重叠区间个数, 需要移除的区间个数 // i 从 1 开始, 要与它前一个区间比较 for i := 1; i < length; i++ { // 当前的左区间在上一个的范围内: 重叠; 只用处理重叠区间即可 if intervals[i][0] < intervals[i-1][1] { count++ intervals[i][1] = min(intervals[i][1], intervals[i-1][1]) } } return count } func min(a, b int) int { if a < b { return a } return b }
2. 划分字母区间
关联 leetcode 763.划分字母区间
-
思路
- 找到当前元素所在的最远位置
- 遍历过去,更新当前区间的最右距离
- 当前区间内元素,所在最远位置
- 直到走到最远位置,清空区间,计算元素个数
- 开启新区间
- 遍历过去,更新当前区间的最右距离
- 找到当前元素所在的最远位置
-
题解
func partitionLabels(s string) []int { distance := [27]int{} //记录每个字母出现的最远位置 // 遍历字符串, 找到每个字母出现的最远位置 for i := 0; i < len(s); i++ { distance[s[i]-'a'] = i } res := make([]int, 0) left, right := 0, 0 //记录当前区间的左右下标, 用于计算区间长度 for i := 0; i < len(s); i++ { right = max(right, distance[s[i]-'a']) if i == right { res = append(res, right-left+1) left = i + 1 } } return res } func max(a, b int) int { if a > b { return a } return b }
3. 合并区间
关联 leetcode 56. 合并区间
-
思路
- 这道题区间边界重叠也算重叠
- 判断两个区间是否重叠,进行区间合并
-
题解
func merge(intervals [][]int) [][]int { length := len(intervals) if length < 2 { return intervals } rets := make([][]int, 0) // 按左区间升序排列 sort.Slice(intervals, func(i, j int) bool { return intervals[i][0] < intervals[j][0] }) rets = append(rets, intervals[0]) //初始化结果集放入第一个区间元素 for i := 1; i < length; i++ { // 区间重叠 if intervals[i][0] <= rets[len(rets)-1][1] { // 更新当前数组最后一个元素: 重叠区间的开始 rets[len(rets)-1][1] = max(intervals[i][1], rets[len(rets)-1][1]) } else { rets = append(rets, intervals[i]) } } return rets } func max(a int, b int) int { if a > b { return a } return b }