算法日记Day3---【题解C++】高访问员工(map+二分+照着题意写代码)

36 阅读2分钟

本篇肯定不是高效的算法设计,只是小白的一次记录和尝试,请dalao留情。

Problem: 100128. 高访问员工

[TOC]

思路

遍历一遍access_times数组,整理出每个员工的访问时间,整合在一个map里,这绝对是很方便的处理,便于我们之后的计算。对于每一位员工,都对他的访问时间做检查,只要访问时间满足题意,就加入答案数组。

解题方法

  1. 一次遍历和map整合后,我们得到了所有员工的访问时间表,一张有序整齐的表。这里还有必要对每一个时刻做一个数据类型转换

  2. 接着为了方便之后的二分查找,我们对每一位员工的访问时间数组都做一次排序。

3.对于每一位员工,从前往后检查它的每一个时刻btime,计算它对应的有边界时刻tTime:

  • 一般情况,tTime=bTime+100-1
  • 可能+1小时都到了第二天,直接tTime=2359
  1. 二分查找upper_bound(),查找tTime的位置pos,接着就能够计算这个区间内的元素(时刻)个数了。细节以及偏移量的处理,请看详细代码。

  2. 对于每一位员工的每一次这样的时刻查询,只要有一次元素个数大于等于3了,就可以将此员工加入答案数组,结束此员工的循环。

复杂度

  • 时间复杂度:

添加时间复杂度, 示例: O(nlogn+n2)O(nlogn+n²)

  • 空间复杂度:

添加空间复杂度, 示例: O(n2)O(n²)

Code


class Solution {
public:
    map<string,vector<int>> m;
    vector<string> stus;
    vector<string> findHighAccessEmployees(vector<vector<string>>& access_times) {
        for(int i=0;i<access_times.size();i++){
            string stu=access_times[i][0];
            int btime=stoi(access_times[i][1]);
            m[stu].push_back(btime);
        }
        map<string,vector<int> >::iterator it=m.begin();
        for(;it!=m.end();it++){
            string str=it->first;
            sort(m[str].begin(),m[str].end());
        }
        //预处理
        it=m.begin();
        for(;it!=m.end();it++)
        {
            string stuff=it->first;
            for(int j=0;j<m[stuff].size();j++){
                int bTime=m[stuff][j],tTime=0;
                if(2300<bTime) tTime=2359;
                else tTime=m[stuff][j]+100-1;

                int n = upper_bound(m[stuff].begin() + j, m[stuff].end(), tTime) - (m[stuff].begin()+j);
                if(n>=3) {
                    stus.push_back(stuff);
                    break;
                }
            }	
        }

        return stus;
    }
};