ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

头条面试题:求用户在线峰值和持续时间

2021-03-16 23:02:40  阅读:188  来源: 互联网

标签:面试题 持续时间 Log int LogoutTime ++ new LoginTime 头条


前几天我的朋友面试头条,给出了这样一道面试题:

有一天的log的数据量,求一天中用户在线峰值和持续时间。

他面试结束后与我讨论,让我也做一下,我晚上就用了点时间做了这个题目。

写完之后我们讨论发现因为思路不同,且他的方法更好,就记录下来跟大家分享一下。

事先声明一个log实体:

    /// <summary>
    /// 登录日志
    /// </summary>
    public class Log
    {
        /// <summary>
        /// 登录时间
        /// </summary>
        public int LoginTime { get; set; }
        /// <summary>
        /// 登出时间
        /// </summary>
        public int LogoutTime { get; set; }
    }

因为只求峰值数据,太多的字段没有加。

创建假数据:

    //模拟数据
    var logs = new List<Log>{
        new Log{ LoginTime=2, LogoutTime=5 },
        new Log{ LoginTime=3, LogoutTime=6 },
        new Log{ LoginTime=3, LogoutTime=4 },
        new Log{ LoginTime=4, LogoutTime=8 },
        new Log{ LoginTime=4, LogoutTime=9 },
        new Log{ LoginTime=4, LogoutTime=10 },
        new Log{ LoginTime=3, LogoutTime=4 },
        new Log{ LoginTime=4, LogoutTime=8 },
        new Log{ LoginTime=5, LogoutTime=6 },
    };

 

以下是我的代码:

            #region 获取每个小时在线人数

            //定义一个数组盛放每个小时的在线人数
            int[] logHigh = new int[24];
            int time = 0;
            while (time < 24)
            {
                logHigh[time] = 0;
                foreach (var log in logs)
                {
                    if (time >= log.LoginTime && time < log.LogoutTime)
                    {
                        logHigh[time]++;
                    }
                }
                time++;
            }

            #endregion
            #region 获取最大在线人数和持续时间

            //获取最大在线人数
            var max = logHigh[0];
            var index = 0;
            for (int j = 1; j < logHigh.Length; j++)
            {
                if (max < logHigh[j])
                {
                    max = logHigh[j];
                    index = j;
                }
            }
            //获取最大在线人数持续时间
            var maxIndex = 0;
            for (var maxI = index + 1; maxI < logHigh.Length; maxI++)
            {
                if (logHigh[maxI] == max)
                {
                    maxIndex = maxI;
                }
                else
                {
                    continue;
                }

            }

            #endregion
            Console.WriteLine("最大在线人数是:" + max);
            Console.WriteLine($"起始时间是:{index},结束时间是:{maxIndex + 1},持续时间:{maxIndex + 1 - index}h");

            for (var i = 0; i < 24; i++)
            {
                Console.WriteLine($"时间在 {i} 到 {i + 1} 点之间在线人数是:{logHigh[i].ToString()}");
            }
            Console.ReadKey();    

运行结果:

  

写完之后我们对结果,没有问题。又互相看了对方的代码,发现逻辑是不一样的。

以下贴出朋友的代码:

            //当天数据容器
            var array = new int[24];

            //初始化数据
            foreach (var item in logs)
            {
                //只记录当前在线人数即可
                for (int i = item.LoginTime; i < item.LogoutTime; i++)
                {
                    array[i]++;
                }
            }

            //统计部分
            int biggest = 0;        //峰值
            int biggestLength = 0;  //持续时长
            int biggestTime = 0;    //最大开始时间

            for (int i = 0; i < array.Length; i++)
            {
                //当前在线人数
                var currentValue = array[i];

                //存储最大峰值
                if (currentValue > biggest)
                {
                    biggest = currentValue;
                    biggestLength = 0;
                    biggestTime = i;
                }

                if (currentValue == biggest)
                    biggestLength++;
            }

            //输出部分
            for (int i = 0; i < array.Length; i++)
            {
                Console.WriteLine($"当前时间:{i} \t 在线人数:{array[i]}");
            }

            Console.WriteLine($"当天最大峰值:{biggest}人,开始时间:{biggestTime}点,持续时间:{biggestLength}h");
            Console.ReadKey();    

运行结果:

不知道大家看出来我们两个逻辑上有什么不同吗?

其实主要的不同是第一部分求每个小时在线人数的思路上的不同:

我的想法是遍历log数据,发现在遍历的时间内就+1;

他的思路是遍历log数据,在数据的开始结束时间内都+1.

他这样做的话就在复杂度上讲多了很多,至少比我少一半的复杂度。

 

如果大家还有什么更好的解法欢迎写在下面。

标签:面试题,持续时间,Log,int,LogoutTime,++,new,LoginTime,头条
来源: https://www.cnblogs.com/jingboweilan/p/14546613.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有