LeetCode-第七个星期

我的日程安排表 II

LeetCode731题,如果出现了第三次区间重叠,则返回false,其余的返回true,该题需要注意细粒度和范围扩大的问题。

实现一个 MyCalendar 类来存放你的日程安排。如果要添加的时间内不会导致三重预订时,则可以存储这个新的日程安排。

MyCalendar 有一个 book(int start, int end)方法。它意味着在 start 到 end 时间内增加一个日程安排,注意,这里的时间是半开区间,即 [start, end), 实数 x 的范围为,  start <= x < end。

当三个日程安排有一些时间上的交叉时(例如三个日程安排都在同一时间内),就会产生三重预订。

每次调用 MyCalendar.book方法时,如果可以将日程安排成功添加到日历中而不会导致三重预订,返回 true。否则,返回 false 并且不要将该日程安排添加到日历中。

请按照以下步骤调用MyCalendar 类: MyCalendar cal = new MyCalendar(); MyCalendar.book(start, end)

 

示例:

MyCalendar();
MyCalendar.book(10, 20); // returns true
MyCalendar.book(50, 60); // returns true
MyCalendar.book(10, 40); // returns true
MyCalendar.book(5, 15); // returns false
MyCalendar.book(5, 10); // returns true
MyCalendar.book(25, 55); // returns true
解释: 
前两个日程安排可以添加至日历中。 第三个日程安排会导致双重预订,但可以添加至日历中。
第四个日程安排活动(5,15)不能添加至日历中,因为它会导致三重预订。
第五个日程安排(5,10)可以添加至日历中,因为它未使用已经双重预订的时间10。
第六个日程安排(25,55)可以添加至日历中,因为时间 [25,40] 将和第三个日程安排双重预订;
时间 [40,50] 将单独预订,时间 [50,55)将和第二个日程安排双重预订。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/my-calendar-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路分析:
1.维护两个TreeMap,键为区间开始点,值为区间结束点。
2.第一个用来记录只出现了一次的区间,并且注意区间的扩展。
3.第二个用来记录重复出现了两次的区间,当新加的区间在此重叠了,就要直接返回false。

  TreeMap<Integer, Integer> singleMap = new TreeMap<>();
    static TreeMap<Integer, Integer> doubleMap = new TreeMap<>();

    public MyCalendarTwo() {

    }


    public boolean book(int start, int end) {
        //获得小于start的最大key值
        Integer a = doubleMap.lowerKey(start);
        //区间重叠
        if (a != null && doubleMap.get(a) > start) {
            return false;
        }
        //获得大于等于start的最小key值
        Integer b = doubleMap.ceilingKey(start);
        //区间重叠
        if (b != null && (b == start || end > b)) {
            return false;
        }
        a = singleMap.lowerKey(start);
        b = singleMap.ceilingKey(start);
        //完全不重叠,和两边的都不挨着
        if ((a == null || singleMap.get(a) <= start) && (b == null || b >= end)) {
            singleMap.put(start, end);
            return true;
        }
        //前区间重叠
        if (a != null && singleMap.get(a) > start) {
            //单个区间扩展
            singleMap.put(a, Math.max(end, singleMap.get(a)));
            //重叠部分加入到double中
            doubleMap.put(start, Math.min(end, singleMap.get(a)));
            //变换需要判断的区间值
            start = a;
            end = Math.max(end, singleMap.get(a));
        }
        //后区间重叠,这时候需要判断当前区间,可能包含的不止一个区间了,所以需要判断的值也不止一个了
        //可以思考为什么前区间不用循环,这里传入的区间足够大的话是可以包含多个后区间的,但最多只能和一个前区间重合
        while (b != null && b < end) {
            Integer i = singleMap.get(b);
            doubleMap.put(b, Math.min(end, i));
            singleMap.remove(b);
            singleMap.put(start, Math.max(end, i));
            end = Math.max(end, i);
            b = singleMap.higherKey(start);
        }
        return true;
    }

车队

LeetCode853题,该题为多辆汽车以不同的出发点和速度行驶在一条路上,当有一辆车追上时,后车就以前车的速度继续行驶,两车形成一个车队。

N  辆车沿着一条车道驶向位于 target 英里之外的共同目的地。

每辆车 i 以恒定的速度 speed[i] (英里/小时),从初始位置 position[i] (英里) 沿车道驶向目的地。

一辆车永远不会超过前面的另一辆车,但它可以追上去,并与前车以相同的速度紧接着行驶。

此时,我们会忽略这两辆车之间的距离,也就是说,它们被假定处于相同的位置。

车队 是一些由行驶在相同位置、具有相同速度的车组成的非空集合。注意,一辆车也可以是一个车队。

即便一辆车在目的地才赶上了一个车队,它们仍然会被视作是同一个车队。

 

会有多少车队到达目的地?

 

示例:

输入:target = 12, position = [10,8,0,5,3], speed = [2,4,1,1,3]
输出:3
解释:
从 10 和 8 开始的车会组成一个车队,它们在 12 处相遇。
从 0 处开始的车无法追上其它车,所以它自己就是一个车队。
从 5 和 3 开始的车会组成一个车队,它们在 6 处相遇。
请注意,在到达目的地之前没有其它车会遇到这些车队,所以答案是 3。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/car-fleet
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路分析:参考了官方的题解,计算每辆车到达终点时的时间,之后按照离终点的距离进行降序排序,这时候数组第一个的离终点最近,如果他到终点的时间小于下一辆车的话,则下辆车永远追不上,说明他们为两个车队,如果大于的话则能追上,到达终点的时间也是一致的。

class Solution {
    public int carFleet(int target, int[] position, int[] speed) {
        int N = position.length;
        Car[] cars = new Car[N];
        for (int i = 0; i < N; ++i)
            cars[i] = new Car(position[i], (double) (target - position[i]) / speed[i]);
        Arrays.sort(cars, (a, b) -> Integer.compare(a.position, b.position));

        int ans = 0, t = N;
        while (--t > 0) {
            if (cars[t].time < cars[t-1].time) ans++; //if cars[t] arrives sooner, it can't be caught
            else cars[t-1] = cars[t]; //else, cars[t-1] arrives at same time as cars[t]
        }
        //t可能会为-1,ans初始值其实最好为1
        return ans + (t == 0 ? 1 : 0); //lone car is fleet (if it exists)
    }
}

class Car {
    int position;
    double time;
    Car(int p, double t) {
        position = p;
        time = t;
    }
}

作者:LeetCode
链接:https://leetcode-cn.com/problems/car-fleet/solution/che-dui-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

最多能完成排序的块 II

LeetCode768,将数组切成多个子块后,排序在按顺序拼接,使得和原来的数组排序后是一致的效果。

这个问题和“最多能完成排序的块”相似,但给定数组中的元素可以重复,输入数组最大长度为2000,其中的元素最大为10**8。

arr是一个可能包含重复元素的整数数组,我们将这个数组分割成几个“块”,并将这些块分别进行排序。之后再连接起来,使得连接的结果和按升序排序后的原数组相同。

我们最多能将数组分成多少块?

示例 1:

输入: arr = [5,4,3,2,1]
输出: 1
解释:
将数组分成2块或者更多块,都无法得到所需的结果。
例如,分成 [5, 4], [3, 2, 1] 的结果是 [4, 5, 1, 2, 3],这不是有序的数组。 
示例 2:

输入: arr = [2,1,3,4,4]
输出: 4
解释:
我们可以把它分成两块,例如 [2, 1], [3, 4, 4]。
然而,分成 [2, 1], [3], [4], [4] 可以得到最多的块数。 

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/max-chunks-to-make-sorted-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路分析:需要记录每个子块中的最大值、当前子块的一个最大值和最小值,当遇到一个数大于当前子块的最大值时,还需判断当前子块的最小值,是否大于前面子块中的所有最大值,如果大于则可以。

        int res = 1;
        int[] pre = new int[arr.length];
        int min = Integer.MAX_VALUE;
        int max = Integer.MIN_VALUE;
        int index = 0;
        for (int i = 1; i < arr.length; i++) {
            max = Math.max(max, arr[i - 1]);
            min = Math.min(min, arr[i - 1]);
            if (max <= arr[i]) {
                while (index > 0 && pre[index - 1] > min) {
                    res--;
                    pre[index - 1] = Math.max(max, pre[--index]);
                }
                pre[index++] = max;
                max = min = arr[i];
                res++;
            }
        }
        min = Math.min(min, arr[arr.length - 1]);
        while (index > 0 && pre[index - 1] > min) {
            res--;
            index--;
        }
        return res;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断
LeetCode-Editor是一种在线编码工具,它提供了一个用户友好的界面编写和运行代码。在使用LeetCode-Editor时,有时候会出现乱码的问题。 乱码的原因可能是由于编码格式不兼容或者编码错误导致的。在这种情况下,我们可以尝试以下几种解决方法: 1. 检查文件编码格式:首先,我们可以检查所编辑的文件的编码格式。通常来说,常用的编码格式有UTF-8和ASCII等。我们可以将编码格式更改为正确的格式。在LeetCode-Editor中,可以通过界面设置或编辑器设置来更改编码格式。 2. 使用正确的字符集:如果乱码是由于使用了不同的字符集导致的,我们可以尝试更改使用正确的字符集。常见的字符集如Unicode或者UTF-8等。在LeetCode-Editor中,可以在编辑器中选择正确的字符集。 3. 使用合适的编辑器:有时候,乱码问题可能与LeetCode-Editor自身相关。我们可以尝试使用其他编码工具,如Text Editor、Sublime Text或者IDE,看是否能够解决乱码问题。 4. 查找特殊字符:如果乱码问题只出现在某些特殊字符上,我们可以尝试找到并替换这些字符。通过仔细检查代码,我们可以找到导致乱码的特定字符,并进行修正或替换。 总之,解决LeetCode-Editor乱码问题的方法有很多。根据具体情况,我们可以尝试更改文件编码格式、使用正确的字符集、更换编辑器或者查找并替换特殊字符等方法来解决这个问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值