首页 > 其他分享 >力扣刷题——855. 考场就座

力扣刷题——855. 考场就座

时间:2024-12-25 16:31:18浏览次数:4  
标签:855 right tem int interval 力扣 second 刷题 first

题目要求进入考场的学生必须是离别人最远的,那么可以想到用一个最大堆维护区间长度,这样每次插入都只需要在堆头部插入新区间即可。
要注意,当区间的一端不在首尾时,区间长度除以2是新加入的学生距离两边的距离;而区间有一端在首尾时,为了方便计算,令左端点为-1,右端点为N,这样,区间长度就等于区间的右端点 - 左端点 - 1
在结构体中又加入了哈希表,分别存储座位的左右座位号,方便删除区间,这种做法有点类似链表。
最后在实现的过程中使用了表达式设定堆的排序方式,确保类的封装性,代码如下:

class ExamRoom {
public:
    int N;
    set<pair<int, int>, std::function<bool(const std::pair<int, int>&, const std::pair<int, int>&)>> interval;
    unordered_map<int, int> left;
    unordered_map<int, int> right;

    ExamRoom(int n) : N(n), interval(compare__())
    {
        
    }

    std::function<bool(const std::pair<int, int>&, const std::pair<int, int>&)> compare__() const 
    {
        return [this](const std::pair<int, int>& a, const std::pair<int, int>& b) 
        {
            int d1, d2;
            if(a.first == -1 || a.second == N)
                d1 = a.second - a.first - 1;
            else
                d1 = (a.second - a.first) / 2;
            
            if(b. first == -1 || b. second == N)
                d2 = b.second - b.first - 1;
            else
                d2 = (b.second - b.first) / 2;

            return d1 == d2 ? a.first < b.first : d1 > d2;
        };
    }

    int seat() 
    {
        if(interval.empty())
        {
            interval.insert({-1, 0});
            interval.insert({0, N});
            left[0] = -1;
            right[-1] = 0;
            left[N] = 0;
            right[0] = N;
            return 0;
        }

        pair<int, int> tem = *interval.begin();
        int p;
        if(tem.first == -1)
        {
            p = 0;
        }
        else if(tem.second == N)
        {
            p = N - 1;
        }
        else
        {
            p = (tem.first + tem.second) / 2;
        }
        
        interval.erase(interval.begin());
        interval.insert({tem.first, p});
        interval.insert({p, tem.second});
        left[p] = tem.first;
        right[p] = tem.second;
        left[tem.second] = p;
        right[tem.first] = p;
        return p;
        
    }
    
    void leave(int p) 
    {
        int a = left[p];
        int b = right[p];
        interval.erase({a, p});
        interval.erase({p, b});
        interval.insert({a, b});
        left.erase(p);
        right.erase(p);
        right[a] = b;
        left[b] = a;
    }
};

标签:855,right,tem,int,interval,力扣,second,刷题,first
From: https://www.cnblogs.com/yuhixyui/p/18630805

相关文章

  • 算法刷题_链表篇
    算法刷题Day8_链表相交文章目录算法刷题Day8_链表相交@[TOC](文章目录)前言一、求出两个链表的长度和差值二、让其中较长一个链表移动到和第二链表对齐的位置三、其他解法_双指针法:总结前言简单来说,就是求两个链表交点节点的指针。一、求出两个链表的长度和差值......
  • leetcode刷题
    思路分析对于每一个房间,只有选或不选两种结果,假设第i个房间选了那么第i-1个房间就不能选。构建状态转移方程dp[i]=max(dp[i-1],dp[i-2]+nums[i]).意思是当偷到第i个房间时,最大的结果应该在偷不偷上一个房间(dp[i-2]+nums[i]也就是偷第i-2个房间和第i个房间的金额)偷上一个房......
  • 1225. 报告系统状态的连续日期 - 力扣(LeetCode)
    目录1.力扣链接2.题目3.分析4.代码实现5.代码验证6.总结1.力扣链接1225.报告系统状态的连续日期-力扣(LeetCode)2.题目表:Failed+--------------+---------+|ColumnName|Type|+--------------+---------+|fail_date|date|+-----......
  • 力扣238. 除自身以外数组的乘积
    给你一个整数数组 nums,返回数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在  32位 整数范围内。请 不要使用除法,且在 O(n) 时间复杂度内完成此题。......
  • 算法刷题Day7_翻转链表
    算法刷题Day7_单链表相关操作文章目录算法刷题Day7_单链表相关操作前言一、反转链表二、两两交换链表中的节点1.递归法2.迭代法总结前言提示:以下是本篇文章正文内容,下面案例可供参考一、反转链表classSolution{public:ListNode*reverseList(ListNode......
  • 算法刷题_删除链表的倒数第N个结点
    算法刷题Day8_删除链表的倒数第N个结点文章目录算法刷题Day8_删除链表的倒数第N个结点前言一、双指针思想二、具体步骤1.定义快慢指针2.fast指针先移动n+1步3.fast和slow一起移动4.删除倒数第N个节点三、完整代码总结前言一、双指针思想双指针的经典应用,如果......
  • 7-13刷题
    7.13刷题[NewStarCTF公开赛赛道]UnserializeOne<?phperror_reporting(0);highlight_file(__FILE__);#Somethingusefulforyou:https://zhuanlan.zhihu.com/p/377676274classStart{public$name;protected$func;publicfunction__destruct()#12当一......
  • 4-14文件上传刷题日记
    buuctf[是兄弟就来传马先传一个php木马页面报错,随便改一个后缀,看看是黑名单还是白名单过滤,这里php代码前加GIF89a绕过图片大小检查报错,接着试一下是不是MIME过滤Content-Type:image/png上传成功/var/www/html/upload/743be915f2c6ab5de3600d87068cafd2/hack.jpgsuccesfu......
  • 1596. 每位顾客最经常订购的商品 - 力扣(LeetCode)
    1596.每位顾客最经常订购的商品-力扣(LeetCode)目标输入表:Productsproduct_idproduct_nameprice1keyboard1202mouse803screen6004harddisk450表:Ordersorder_idorder_datecustomer_idproduct_id12020/7/311122020/7/302232020/8/293342020/7/294152020/6/101262020/8/1......
  • 【多维DP】【准NOI难度】力扣3251. 单调数组对的数目 II
    给你一个长度为n的正整数数组nums。如果两个非负整数数组(arr1,arr2)满足以下条件,我们称它们是单调数组对:两个数组的长度都是n。arr1是单调非递减的,换句话说arr1[0]<=arr1[1]<=…<=arr1[n-1]。arr2是单调非递增的,换句话说arr2[0]>=ar......