leetcode 刷题_day38_贪心05_局部最优推出全局最优

435. 无重叠区间

思路

452. 用最少数量的箭引爆气球 一样的思路

为贪心算法的区间问题。

解题方法

  1. 排序
  2. 遍历,重合的话取最小的右边界作为截取点

复杂度

  • 时间复杂度:

添加时间复杂度, 示例: O ( n l o g n ) O(nlogn) O(nlogn)

  • 空间复杂度:

添加空间复杂度, 示例: O ( n ) O(n) O(n)

Code


class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {

        // 排序,左边界升序,二重右边界升序,注意,不排右边界也一样
        Arrays.sort(intervals, (a, b) -> {
            int c = Integer.compare(a[0], b[0]);
            if (c == 0) {
                return Integer.compare(a[1], b[1]);
            }
            return c;
        });

        int result = 0;
        // 取第一个位置的右边界为截取点
        int pre = intervals[0][1];

        // 相交的时候取最小的右边
        for(int i = 1; i < intervals.length; i++) {
            if (intervals[i][0] < pre) {
                result++;
                pre = Math.min(pre, intervals[i][1]);
            } else {
                pre = intervals[i][1];
            }
        }

        return result;
    }
}

763. 划分字母区间

思路

讲述看到这一题的思路
image.png

解题方法

  1. 记录 s 中各个字母的最远位置
  2. 持续更新最远位置,直到最远位置等于i,开启下一段区间

复杂度

  • 时间复杂度: O ( n ) O(n) O(n)

  • 空间复杂度: O ( 1 ) O(1) O(1)

Code


class Solution {
    public List<Integer> partitionLabels(String s) {
        List<Integer> result = new ArrayList<>();

        // 记录 s 中各个字母的最远位置
        int[] farPos = new int[26];
        for (int i = 0; i < s.length(); i++) {
            farPos[s.charAt(i) - 'a'] = i;
        }

        // 持续更新最远位置,直到最远位置等于i,开启下一段区间
        int start = 0;
        int end = 0;
        for (int i = 0; i < s.length(); i++) {
            end = Math.max(farPos[s.charAt(i) - 'a'], end);
            if (i == end) {
                result.add(end - start + 1);
                start = end + 1;
            }
        }

        return result;
    }
}

56. 合并区间

思路

讲述看到这一题的思路

解题方法

  1. 排序
  2. 遍历,判断边界条件

复杂度

  • 时间复杂度:

添加时间复杂度, 示例: O ( n ) O(n) O(n)

  • 空间复杂度:

添加空间复杂度, 示例: O ( n ) O(n) O(n)

Code


class Solution {

    // 1. 排序
    // 2. 遍历,判断边界条件
    public int[][] merge(int[][] intervals) {
        Arrays.sort(intervals, (a, b) -> a[0] - b[0]);

        List<int[]> result = new LinkedList<>();
        // 合并区间边界,初始化
        int start = intervals[0][0];
        int end = intervals[0][1];

        for (int i = 1; i < intervals.length; i++) {
            // 当前区间左边界和上一个合并区间右边界重叠,更新重叠区间右边界
            if (end >= intervals[i][0]) {
                end = Math.max(end, intervals[i][1]);
            } else {
                result.add(new int[]{start, end});

                // 更新下一个重叠区间
                start = intervals[i][0];
                end = intervals[i][1];
            }
        }

        // 收尾处理
        result.add(new int[]{start, end});

        return result.toArray(new int[result.size()][]);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值