前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >LeetCode 1912. 设计电影租借系统(map+set)

LeetCode 1912. 设计电影租借系统(map+set)

作者头像
Michael阿明
发布2021-09-06 11:15:56
5840
发布2021-09-06 11:15:56
举报
文章被收录于专栏:Michael阿明学习之路

文章目录

1. 题目

你有一个电影租借公司和 n 个电影商店。 你想要实现一个电影租借系统,它支持查询、预订和返还电影的操作。 同时系统还能生成一份当前被借出电影的报告。

所有电影用二维整数数组 entries 表示,其中 entries[i] = [shopi, moviei, pricei] 表示商店 shopi 有一份电影 moviei 的拷贝,租借价格为 pricei 。 每个商店有 至多一份 编号为 moviei 的电影拷贝。

系统需要支持以下操作:

  • Search:找到拥有指定电影未借出 的商店中 最便宜的 5 个 。 商店需要按照 价格 升序排序, 如果价格相同,则 shopi 较小 的商店排在前面。 如果查询结果少于 5 个商店,则将它们全部返回。 如果查询结果没有任何商店,则返回空列表。
  • Rent:从指定商店借出指定电影,题目保证指定电影在指定商店 未借出 。
  • Drop:在指定商店返还 之前已借出 的指定电影。
  • Report:返回 最便宜的 5 部已借出电影 (可能有重复的电影 ID),将结果用二维列表 res 返回, 其中 res[j] = [shopj, moviej] 表示第 j 便宜的已借出电影是从商店 shopj 借出的电影 moviej 。 res 中的电影需要按 价格 升序排序; 如果价格相同,则 shopj 较小 的排在前面; 如果仍然相同,则 moviej 较小 的排在前面。 如果当前借出的电影小于 5 部,则将它们全部返回。 如果当前没有借出电影,则返回一个空的列表。

请你实现 MovieRentingSystem 类:

  • MovieRentingSystem(int n, int[][] entries) 将 MovieRentingSystem 对象用 n 个商店和 entries 表示的电影列表初始化。
  • List<Integer> search(int movie) 如上所述,返回 未借出 指定 movie 的商店列表。
  • void rent(int shop, int movie) 从指定商店 shop 借出指定电影 movie 。
  • void drop(int shop, int movie) 在指定商店 shop 返还之前借出的电影 movie 。
  • List<List<Integer>> report() 如上所述,返回最便宜的 已借出 电影列表。

注意:测试数据保证 rent 操作中指定商店拥有 未借出 的指定电影,且 drop 操作指定的商店 之前已借出 指定电影。

代码语言:javascript
复制
示例 1:
输入:
["MovieRentingSystem", "search", "rent", "rent", "report", "drop", "search"]
[[3, [[0, 1, 5], [0, 2, 6], [0, 3, 7], [1, 1, 4], [1, 2, 7], [2, 1, 5]]], [1], [0, 1], [1, 2], [], [1, 2], [2]]
输出:
[null, [1, 0, 2], null, null, [[0, 1], [1, 2]], null, [0, 1]]

解释:
MovieRentingSystem movieRentingSystem = new MovieRentingSystem(3, [[0, 1, 5], [0, 2, 6], [0, 3, 7], [1, 1, 4], [1, 2, 7], [2, 1, 5]]);
movieRentingSystem.search(1);  // 返回 [1, 0, 2] ,商店 1,0 和 2 有未借出的 ID 为 1 的电影。商店 1 最便宜,商店 0 和 2 价格相同,所以按商店编号排序。
movieRentingSystem.rent(0, 1); // 从商店 0 借出电影 1 。现在商店 0 未借出电影编号为 [2,3] 。
movieRentingSystem.rent(1, 2); // 从商店 1 借出电影 2 。现在商店 1 未借出的电影编号为 [1] 。
movieRentingSystem.report();   // 返回 [[0, 1], [1, 2]] 。商店 0 借出的电影 1 最便宜,然后是商店 1 借出的电影 2 。
movieRentingSystem.drop(1, 2); // 在商店 1 返还电影 2 。现在商店 1 未借出的电影编号为 [1,2] 。
movieRentingSystem.search(2);  // 返回 [0, 1] 。商店 0 和 1 有未借出的 ID 为 2 的电影。商店 0 最便宜,然后是商店 1 。
 
提示:
1 <= n <= 3 * 10^5
1 <= entries.length <= 10^5
0 <= shopi < n
1 <= moviei, pricei <= 10^4
每个商店 至多 有一份电影 moviei 的拷贝。
search,rent,drop 和 report 的调用 总共 不超过 10^5 次。

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

2. 解题

代码语言:javascript
复制
class MovieRentingSystem {
    unordered_map<int, set<pair<int,int>>> unborrowed; //movie : <price, shop>
    set<vector<int>> borrowed; // <price, shop, movie>
    unordered_map<long long, int> m; // shop*k+movie, price, 根据 shop,movie,获取其 price
    long long k = 10001;
public:
    MovieRentingSystem(int n, vector<vector<int>>& entries) {
        for(auto& e : entries)
        {
            unborrowed[e[1]].insert({e[2], e[0]});
            m[e[0]*k+e[1]] = e[2];
        }
    }
    
    vector<int> search(int movie) {
        if(unborrowed.find(movie) == unborrowed.end())
            return {};
        auto it = unborrowed[movie].begin();
        int i = 0;
        vector<int> ans;
        while(i < 5 && it != unborrowed[movie].end()) // 未借出电影的最便宜的5家店
        {
            ans.push_back((*it).second);
            i++;
            it++;
        }
        return ans;
    }
    
    void rent(int shop, int movie) {
        int price = m[shop*k+movie];
        borrowed.insert({price, shop, movie});//借出
        unborrowed[movie].erase({price, shop});
        if(unborrowed[movie].empty())
            unborrowed.erase(movie);
    }
    
    void drop(int shop, int movie) {
        int price = m[shop*k+movie];
        borrowed.erase({price, shop, movie});
        unborrowed[movie].insert({price, shop});//归还
    }
    
    vector<vector<int>> report() {
        auto it = borrowed.begin();
        int i = 0;
        vector<vector<int>> ans;
        while(i < 5 && it != borrowed.end())//借出里面最便宜的5本
        {
            ans.push_back({(*it)[1], (*it)[2]});
            i++;
            it++;
        }
        return ans;
    }
};

1268 ms 298.5 MB C++


我的CSDN博客地址 https://michael.blog.csdn.net/

长按或扫码关注我的公众号(Michael阿明),一起加油、一起学习进步!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/06/27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 1. 题目
  • 2. 解题
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档