代码随想录day31|435无重叠区间763划分字母区间56合并区间|01笔记

71 阅读1分钟
  • 435无重叠区间

  • 代码随想录 (programmercarl.com)
  • 第一印象

  • 排序是必要的,难点在于如何统计同时与多个区间重叠的区间。
  • 讲解观后感

  • 排序的方式选择用左边界还是有边界进行排序,决定了统计重叠区间还是非重叠区间更合适。在排序左边界的方法中,统计的方法核心逻辑是判断最小右边界与当前区间的重叠关系;排序右边界的方法则是离开一组重叠区间任意一个的右边即可。
  • 解题代码

  • 排序右边界
  •     func eraseOverlapIntervals(intervals [][]int) int {
            sort.Slice(intervals, func(i, j int) bool {
                return intervals[i][1] < intervals[j][1]
            })
            unOl := 1
            end := intervals[0][1]
            for i := 1; i < len(intervals); i++ {
                if end <= intervals[i][0] {
                    end = intervals[i][1]
                    unOl++
                }
            }
            return len(intervals) - unOl
        }
        
    
  • 排序左边界
  •     func eraseOverlapIntervals(intervals [][]int) int {
            sort.Slice(intervals, func(i, j int) bool {
                return intervals[i][0] < intervals[j][0]
            })
            res := 0
            end := intervals[0][1]
            for i := 1; i < len(intervals); i++ {
                if intervals[i][0] < end {
                    res++
                    end = min(end, intervals[i][1])
                } else {
                    end = intervals[i][1]
                }
                
            }
            return res
        }
        func min(a, b int) int {
            if a < b {
                return a
            }
            return b
        }
    
  • 打气球改写法
  •     func eraseOverlapIntervals(intervals [][]int) int {
            sort.Slice(intervals, func(i, j int) bool {
                return intervals[i][1] < intervals[j][1]
            })
            res := 1
            for i := 1; i < len(intervals); i++ {
                if intervals[i][0] >= intervals[i-1][1] {
                    res++
                } else {
                    intervals[i][1] = min(intervals[i - 1][1], intervals[i][1])
                }
            }
            return len(intervals) - res
        }
        func min(a, b int) int {
            if a < b {
                return a
            }
            return b
        }
    
  • 763划分字母区间

  • 代码随想录 (programmercarl.com)
  • 第一印象

  • 感觉可以一次判断每个字母在前面有没有出现过,没有出现过片段则加一,出现过则根据位置重置片段统计数。但是判断出现的存储逻辑很难构建。
  • 讲解观后感

  • 统计数字最远出现的下标,实在是巧妙的方法。如果找到之前遍历过的所有字母的最远边界,说明这个边界就是分割点了
  • 解题代码

  •     func partitionLabels(s string) []int {
            var res []int;
            var marks [26]int;
            left, right :=0, 0;
            for i := 0; i < len(s); i++ {
                marks[s[i] - 'a'] = i;
            }
            for i := 0; i < len(s); i++ {
                right = max(right, marks[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 {
                a = b;
            }
            return a;
        }
    
  • 56合并区间

  • 代码随想录 (programmercarl.com)
  • 第一印象

  • 同时维护前一个区间和当前区间,判定是否重叠,如果重叠则更新当前区间的范围,删除前一个区间,并将当前区间赋值到上一个区间值。
  • 讲解观后感

  • 重叠区间的题目的判定都是一样的逻辑,先通过左边界或者右边界进行排序,然后再构建判断和处理逻辑。
  • 本题再通过双指针的方式更新边界,就可以省略每次更新新区间的过程,而是没有重叠的时候再压入结果集。
  • 解题代码

  • 左边界排序
  •     func merge(intervals [][]int) [][]int {
            sort.Slice(intervals, func(i, j int) bool {
                return intervals[i][0] < intervals[j][0]
            })
            res := make([][]int, 0, len(intervals))
            left, right := intervals[0][0], intervals[0][1]
            for i := 1; i < len(intervals); i++ {
                if right < intervals[i][0] {
                    res = append(res, []int{left, right})
                    left, right = intervals[i][0], intervals[i][1]
                } else {
                    right = max(right, intervals[i][1])
                }
            }
            res = append(res, []int{left, right})  // 将最后一个区间放入
            return res
        }
        func max(a, b int) int {
            if a > b {
                return a
            }
            return b
        }