【LeetCode-系统设计1】

电梯上下

某大楼有一部电梯,初始电梯内没有乘客,乘客出现顺序保存在数组 passengers 中,passengers[i]格式为from to,分别表示乘客所在的楼层和想去的楼层。
假设乘客按顺序一个一个出现,当前乘客 passengers[i] 进入电梯且电梯关门后,后一个乘客 passengers[i+1] 立刻出现并等待。
电梯搭载规则如下:

·         当电梯内无乘客时,立即去接当前等待乘客。

·         当电梯内有乘客时:

·         将电梯内乘客都送到之前,电梯不会改变运行方向。

·         若电梯经过当前等待乘客所在楼层、且运行方向与当前等待乘客想去的方向一致,就会顺路搭载当前等待乘客。

假设电梯能携带的乘客数量没有限制,请计算电梯运送完最后一个乘客时,总共运行了多少层的距离。
输入
首行两个整数num initFloor,分别表示乘客的个数和电梯初始所在的楼层,1 <= num <= 1001 <= initFloor <= 100
接下来 num 行表示passengers信息,passengers[i]格式为from to,分别表示乘客所在的楼层和想去的楼层,1 <= from <= 1001 <= to <= 100,from != to
输出
一个整数,表示电梯总共运行了多少层的距离

样例
输入样例 1
3 50
12 66
25 27
26 83
输出样例 1

109
输入样例 1
4 50

50 10
40 20
30 100
30 100

输出样例 1
270

class Solution {
public:
    bool isS(pair<int, int> info, bool upOrDown, int curSFloor) {
        int startF = info.first;
        int endF = info.second;

        bool curUOD = startF > endF ? false : true;

        // true 升序
        if (curUOD) {
            if (startF > curSFloor) {
                return true;
            }
        } else { // 降序
            if (startF < curSFloor) {
                return true;
            }
        }

        return false;
    }
    int CalcDistance(int initFloor, vector<pair<int, int>>& peopleInfo) {
        // 初始信息
        int curSFloor = peopleInfo[0].first;
        int curEFloor = peopleInfo[0].second;

        // up - true  down - false
        bool upOrDown = (curSFloor > curEFloor) ? false : true;
        int res = abs(initFloor - curSFloor);
        for (int i = 1; i < peopleInfo.size(); i++) { // 可以从0开始也可以从1开始

            vector<int> floor;
            while (isS(peopleInfo[i], upOrDown, curSFloor) && i < peopleInfo.size()) { 
                floor.push_back(peopleInfo[i].first);
                floor.push_back(peopleInfo[i].second);
                i++; // 内层自加的时候,while循环需要校验索引
            }

            floor.push_back(curEFloor); // 起始元素需要最后存入
            floor.push_back(curSFloor);

            // 结束for循环
            // 统计步数  更新起始位置
            sort(floor.begin(), floor.end());
            for (int j = 0; j < floor.size() - 1; j++) {
                res += abs(floor[j] - floor[j + 1]);
            }

            if (i < peopleInfo.size()) { // 增加校验,如果一直循环结束,i索引超过范围
                // 更新起始位置
                curSFloor = peopleInfo[i].first;
                curEFloor = peopleInfo[i].second;

                int last = upOrDown ? floor[floor.size() - 1] : floor[0]; // 升序取最大,降序取最小
                res += abs(last - curSFloor);
                upOrDown = (curSFloor > curEFloor) ? false : true;
            } else {
                return res; // 超过索引直接返回结果
            }


        }
        return res + abs(curSFloor - curEFloor); // 最后单独一次在return的时候更新(while循环在里层更新完返回)
    }
};

生产线AC-难忘的体验!!

class ProductionLineMgmtSys {
public:
    map<int, int> numPer;
    ProductionLineMgmtSys(int num, const vector<int>& periods)
    {
        for (int i = 0; i < periods.size(); i++) {
            numPer[i] = periods[i];
        }
    }

    map<int, int> assemblyPro;
    map<int, vector<tuple<int, int, int>>> mp;
    int Produce(int date, int assemblyId, int productId)
    {
        if (!assemblyPro.count(assemblyId)) {
            assemblyPro[assemblyId] = productId;

            mp[assemblyId].push_back(make_tuple(productId, date, -1));
            return 1;
        }
        if (assemblyPro.count(assemblyId)) {
            if (assemblyPro[assemblyId] == productId) {
                return 0;
            } else {
                get<2>(mp[assemblyId].back()) = date;
            }
        }

        assemblyPro[assemblyId] = productId;
        mp[assemblyId].push_back(make_tuple(productId, date, -1));
        return -1;
    }

    int GetProductCount(int date, int productId)
    {
        vector<tuple<int, int>> target;
        for (auto ele : mp) {
            vector<tuple<int, int, int>> vec = ele.second;
            for (auto e : vec) {
                if (get<0>(e) == productId) {
                    if (get<2>(e) == -1) {
                        target.push_back(make_tuple(get<1>(e), date));
                    } else {
                        target.push_back(make_tuple(get<1>(e), get<2>(e)));
                    }
                }
            }
        }

        int count = 0;
        int per = numPer[productId];
        for (int i = 0; i < target.size(); i++) {
            int start = get<0>(target[i]);
            int end = get<1>(target[i]);

            int cur = start + per;
            while (cur <= end) {
                count++;
                cur += per;
            }
        }
        return count;
    }
};

系统设计_步数冠军_求最大值变化的次数.cpp

// 求最大值变化的次数,最大值可能同时是多个id
// 多个最大值的id,所以数据结构vector<int>,最终比较vec是否有变化即可
// 剩下考虑的就是怎么求每天的最大值,同时把最大值对应的索引倒推出来,再比较vec
// 涉及到比较一定有pre的变量,比较完,将pre更新

class Solution {
public:
    vector<int> getIndex(vector<int> baseScores, int maxScore) {
        vector<int> index;
        for (int i = 0; i < baseScores.size(); i++) {
            if (maxScore == baseScores[1]) {
                index.push_back(i); // id顺序排序,这里不需要考虑id是否是乱序的
            }
        }
        return 
    }

    int ChangeRanking(vector<int> &baseScores, vector<vector<int>> &ranks) {
        map<int, vector<tuple<int, int>>> ranksMap;
        for (auto rank : ranks) {
            int day = rank[0];
            int id = rank[1];
            int step = rank[2];

            ranksMap[day].push_back(make_tuple(id, step));
        }

        // 每天怎么去处理
        int totalDay = ranksMap.size(); // 每天一个索引
        int maxScore = *max_element(baseScores.begin(), baseScores.end()); // 可能存在多个索引

        // 封装,直接返回vec
        vector<int> preIdxVec = getIndex(baseScores, maxScore);

        int res = 0;
        for (int i = 1; i <= totalDay; i++) {
            auto iter = find(ranksMap.begin(), ranksMap.end(), i);
            if (iter == ranksMap.end()) {
                // 求当前最大值(没找到,最大值不会更新,直接继续遍历就行,这种隐含的逻辑都没有悟出来???)
                // 这种没有找的可以最后处理,先把大的框架写出来!!!!!!写的时候考虑太多,不容易聚焦
                continue;
            }

            for (auto ele : iter->second) {
                int curId = get<0>(ele);
                int curStep = get<1>(ele);

                baseScores[curId] += curStep; // 更新步数
            }

            maxScore = *max_element(baseScores.begin(), baseScores.end());
            vector<int> curIdxVec = getIndex(baseScores, maxScore);;

            // 每次找到的都是最大值,不管这个最大值是变大还是变小,都会更新榜单
            // 一定会把上一次的索引更新(这个点必须是本周和上周比较,必须把上周的结果存储下来)
            if (curIdxVec.size() != preIdxVec.size() || curIdxVec != preIdxVec) {
                res++;
            }
            preIdxVec = curIdxVec;
        }
        return res;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值