【精】LintCode领扣算法问题答案:1897. 会议室 3

本文详细解析LintCode上的1897. 会议室 3问题,探讨如何在给定的会议室资源下,判断新增会议是否能顺利安排。文章提供分析思路及解决方案,适合算法学习者参考。

非常感谢你阅读本文,欢迎【👍点赞】【⭐收藏】【📝评论】~
放弃不难,但坚持一定很酷!希望我们大家都能每天进步一点点!🎉
本文由 二当家的白帽子 https://le-yi.blog.csdn.net/ 博客原创,转载请注明来源,谢谢~



1897. 会议室 3

你有一个当前会议列表intervals,里面表明了每个会议的开始和结束时间,以及一些会议室rooms。现在有一系列会议ask需要加入,逐个判断他们能否被安排进当前的会议列表中而不产生冲突。一个会议室在同一时间只能进行一场会议。每个询问都相互独立。

  • 保证输入可以被安排在rooms个会议室之中
  • 保证任意一个会议的结束时间不大于50000
  • |Intervals| <= 50000
  • |ask| <= 50000
  • rooms <= 20

样例 1:

输入:
	Intervals:[[1,2],[4,5],[8,10]],rooms = 1,ask: [[2,3],[3,4]]
输出: 
	[true,true]
解释:
	对于[2,3]的询问,我们可以安排一个会议室room0。
	以下是room0的会议列表:
	[[1,2],[2,3],[4,5],[8,10]]
	对于[3,4]的询问,我们可以安排一个会议室room0。
	以下是room0的会议列表:
	[[1,2],[3,4],[4,5],[8,10]]

样例 2:

输入:
	[[1,2],[4,5],[8,10]]
	1
	[[4,5],[5,6]]
输出:
	[false,true]

分析

题目说“每个询问都相互独立”,所以每次询问我们要找的就是那个时间段是否有一间空着的会议室。题目还说“保证输入可以被安排在rooms个会议室之中”,所以只有会议室被占满的时间段里无法再安排一个会议。我们把输入里会议室占满的时间段记录下来,然后询问时直接查找是否有记录,就可以快速判断是否可以安排会议。


题解

public class Solution {
    /**
     * @param intervals: the intervals
     * @param rooms: the sum of rooms
     * @param ask: the ask
     * @return: true or false of each meeting
     */
    public boolean[] meetingRoomIII(int[][] intervals, int rooms, int[][] ask) {
        // Write your code here.

        // 计数
        // 最开始用的map,但是会超时
        int[] counter = new int[500001];
        for (int[] interval : intervals) {
            // 开始的时候使用量增加
            ++counter[interval[0]];
            // 结束的时候使用量减少
            --counter[interval[1]];
        }

        // 将使用量达到会议室总数的范围放入pos
        List<int[]> pos    = new ArrayList<>();
        // 某个时间点在使用的会议室数量
        int         preSum = 0;
        for (int i = 0; i < counter.length; ++i) {
            int key   = i;
            int value = counter[i];
            preSum += value;

            if (preSum == rooms) {
                do {
                    ++i;
                } while (counter[i] == 0);
                preSum += counter[i];
                pos.add(new int[]{key, i});
            }
        }

        // 结果查找
        boolean[] res = new boolean[ask.length];
        for (int i = 0; i < ask.length; i++) {
            res[i] = !this.binarySearch(pos, ask[i]);

        }
        return res;
    }

    /**
     * 二分查找
     * @param intervals
     * @param a
     * @return
     */
    private boolean binarySearch(List<int[]> intervals, int[] a) {
        int low  = 0;
        int high = intervals.size() - 1;

        while (low <= high) {
            int   mid      = (low + high) >>> 1;
            int[] interval = intervals.get(mid);

            if (a[0] >= interval[1])
                low = mid + 1;
            else if (a[1] <= interval[0])
                high = mid - 1;
            else
                return true; // key found
        }
        return false;  // key not found.
    }
}

原题传送门


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

二当家的白帽子

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

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

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

打赏作者

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

抵扣说明:

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

余额充值