力扣每日一题——在既定时间做作业的学生人数

题目链接:1450. 在既定时间做作业的学生人数 - 力扣(LeetCode)

注:下述题目描述和示例均来自力扣


题目描述 

给你两个整数数组 startTime(开始时间)和 endTime(结束时间),并指定一个整数 queryTime 作为查询时间。

已知,第 i 名学生在 startTime[i] 时开始写作业并于 endTime[i] 时完成作业。

请返回在查询时间 queryTime 时正在做作业的学生人数。形式上,返回能够使 queryTime 处于区间 [startTime[i], endTime[i]](含)的学生人数。


示例

示例一:

示例 1:

输入:startTime = [1,2,3], endTime = [3,2,7], queryTime = 4
输出:1
解释:一共有 3 名学生。
第一名学生在时间 1 开始写作业,并于时间 3 完成作业,在时间 4 没有处于做作业的状态。
第二名学生在时间 2 开始写作业,并于时间 2 完成作业,在时间 4 没有处于做作业的状态。
第三名学生在时间 3 开始写作业,预计于时间 7 完成作业,这是是唯一一名在时间 4 时正在做作业的学生。

示例 2:

输入:startTime = [4], endTime = [4], queryTime = 4
输出:1
解释:在查询时间只有一名学生在做作业。

示例 3:

输入:startTime = [4], endTime = [4], queryTime = 5
输出:0

示例 4:

输入:startTime = [1,1,1,1], endTime = [1,3,2,4], queryTime = 7
输出:0

示例 5:

输入:startTime = [9,8,7,6,5,4,3,2,1], endTime = [10,10,10,10,10,10,10,10,10], queryTime = 5
输出:5

提示:

  • startTime.length == endTime.length
  • 1 <= startTime.length <= 100
  • 1 <= startTime[i] <= endTime[i] <= 1000
  • 1 <= queryTime <= 1000

解法一:枚举(秒杀)

        实现思路是通过遍历startTime和endTime数组,对比每个学生的开始时间和结束时间与查询时间的关系,将满足条件的学生数量加1,并返回最后的结果。具体的实现步骤如下:

  1. 初始化变量len为startTime数组的长度,表示学生数量。
  2. 初始化变量index为0,表示当前遍历的学生下标。
  3. 初始化变量res为0,表示满足条件的学生数量。
  4. 进入循环,每次循环减少len的值。
  5. 检查当前学生的开始时间startTime[index]是否小于等于查询时间queryTime,并且结束时间endTime[index]是否大于等于查询时间queryTime。如果满足这两个条件,则将res加1。
  6. 将index加1,以便遍历下一个学生的开始时间和结束时间。
  7. 循环结束后,返回res作为结果。

        整体思路是通过遍历学生的开始时间和结束时间,检查每个学生是否在查询时间范围内,然后对满足条件的学生数量进行统计。

class Solution {
    public int busyStudent(int[] startTime, int[] endTime, int queryTime) {
        int len = startTime.length;
        int index = 0;
        int res = 0;
        while(len > 0){
            len--;
            if(queryTime >= startTime[index] && 
               queryTime <= endTime[index]){
                res++;
            }
            index++;
        }
        return res;
    }
}

根据这题的测试数据规模真的是太简单了,暴力都能过

 


解法二:二分查找

        这次的二分纯粹是为了秀肌肉的产物,一点提升没有甚至时间复杂度还增加为了nlogn这你受得鸟吗?
 

  • 排序:

    • 使用 Arrays.sort()startTimeendTime 进行排序,以便二分查找能够正常工作。
  • upperBound 和 lowerBound 的实现:

    • upperBound: 查找第一个大于 queryTime 的元素的索引位置,等价于 C++ 中的 upper_bound
    • lowerBound: 查找第一个不小于 queryTime 的元素的索引位置,等价于 C++ 中的 lower_bound
  • 计算:

    • lessStart 表示开始时间小于等于 queryTime 的学生数量。
    • lessEnd 表示结束时间小于 queryTime 的学生数量。
    • 最后返回 lessStart - lessEnd 作为在 queryTime 时正在做作业的学生人数。

 

class Solution {
    public int busyStudent(int[] startTime, int[] endTime, int queryTime) {
        // 将startTime和endTime数组排序
        Arrays.sort(startTime);
        Arrays.sort(endTime);
        
        // 使用二分查找计算小于等于queryTime的startTime数量
        int lessStart = upperBound(startTime, queryTime);
        
        // 使用二分查找计算小于queryTime的endTime数量
        int lessEnd = lowerBound(endTime, queryTime);
        
        // 返回两者之差
        return lessStart - lessEnd;
    }

    // 实现upper_bound等价的函数
    private int upperBound(int[] arr, int target) {
        int left = 0, right = arr.length;
        while (left < right) {
            int mid = left + (right - left) / 2;
            if (arr[mid] <= target) {
                left = mid + 1;
            } else {
                right = mid;
            }
        }
        return left;
    }

    // 实现lower_bound等价的函数
    private int lowerBound(int[] arr, int target) {
        int left = 0, right = arr.length;
        while (left < right) {
            int mid = left + (right - left) / 2;
            if (arr[mid] < target) {
                left = mid + 1;
            } else {
                right = mid;
            }
        }
        return left;
    }
}

 

        果然暴力才是这个世界上最优美的算法 !!


总结

        貌似通过二分来解决这个问题,实在是多写太多东西了,不如暴力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WenJGo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值