Day38~435. 无重叠区间、763.划分字母区间、56. 合并区间

74 阅读3分钟

摘要

本文主要介绍了LeetCode贪心算法的几个题目,包括435. 无重叠区间、763.划分字母区间、56. 合并区间。

1、435.无重叠区间

1.1 思路

  • 同452. 用最少数量的箭引爆气球
  • 如果当前元素的左边界小于前一个元素的右边界,重叠数量+1,并且设置当前元素的右边界等于当前元素和前一个元素有边界的最小值
  • 反之则代码当前元素与前一个元素不重叠

1.2 代码

    public int eraseOverlapIntervals(int[][] intervals) {
        Arrays.sort(intervals, (a, b) -> {
            if(a[0] == b[0]) {
                return a[1] - b[1];
            }
            return a[0] - b[0];
        });
​
        int count = 0;
        for(int i=1; i<intervals.length; i++) {
            if(intervals[i][0] < intervals[i-1][1]) {
                intervals[i][1] = Math.min(intervals[i-1][1], intervals[i][1]);
                count++;
            }
        }
        return count;
    }

2、763.划分字母区间

2.1 思路

  • 遍历字符串,记录每个字母最后出现的位置: 你需要遍历给定的字符串,对于每个字母,记录它在字符串中最后出现的位置。这个信息将帮助你确保同一字母出现在同一子串中。
  • 贪心分割子串: 从字符串的开头开始遍历,维护两个指针,startendstart 指示当前子串的起始位置,而 end 用于遍历字符串并找到可以分割子串的位置。
  • 在遍历过程中更新 end 对于当前遍历的字母,你需要查找它最后出现的位置,并将 end 更新为这个位置。这样,你就可以确保当前子串中包含了该字母的所有出现。
  • 判断是否可以分割子串:i(当前遍历的位置)等于 end 时,说明当前子串中的所有字母都已经包含在内。此时,你可以将该子串分割出来,并将 start 更新为 i+1,继续遍历剩下的字符串。
  • 重复步骤 3 和步骤 4,直到遍历完成: 重复这个过程,直到遍历完整个字符串,每次分割子串时,都能确保同一字母出现在同一子串中。
  • 最终的结果是各个子串的长度: 分割完成后,你可以得到各个子串的长度,这些长度即为答案。

2.2 代码

    // 记录最远处a的位置,这个位置之前一定把所有的a都包含了
    // for循环遍历数组,定义left,right,如果i=right 则表示满足划分条件
    public List<Integer> partitionLabels(String s) {
        int[] arr = new int[26];
        for(int i=0; i<s.length(); i++) {
            arr[s.charAt(i)-'a'] = i;
        }
​
        List<Integer> res = new ArrayList<>();
        int left = 0;
        int right = 0;
        for(int i=0; i<s.length(); i++) {
           right = Math.max(right, arr[s.charAt(i)-'a']);
           if(i == right) {
               res.add(right-left+1);
               left = right + 1;
           }
        }
        return res;
    }

3、56. 合并区间

3.1 思路

  • 同452. 用最少数量的箭引爆气球
  • 如果当前元素的左边界大于前一个元素的右边界(end),即将当前元素加入结果中
  • 反之更新当前元素的右边界为当前元素与前一个元素右边界的最大值

3.2 代码

    public int[][] merge(int[][] intervals) {
        Arrays.sort(intervals, (a, b) -> {
            return Integer.compare(a[0], b[0]);
        });
​
        List<int[]> res = new ArrayList<>();
        int start = intervals[0][0];
        int end = intervals[0][1];
        for(int i=1; i<intervals.length; i++) {
            if(intervals[i][0] > end) {
                res.add(new int[]{start, end});
                start = intervals[i][0];
                end = intervals[i][1];
            } else {
                end = Math.max(end, intervals[i][1]);
            }
        }
        res.add(new int[]{start, end});
        return res.toArray(new int[res.size()][]);
    }

参考资料

代码随想录-435.无重叠区间

代码随想录-763.划分字母区间

代码随想录-56. 合并区间