前幾天我的朋友面試頭條,給出了這樣一道面試題:
有一天的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 =https://www.cnblogs.com/jingboweilan/p/ array[i]; //存盤最大峰值 if (currentValue > biggest) { biggest = currentValue; biggestLength = 0; biggestTime = i; } if (currentValue =https://www.cnblogs.com/jingboweilan/p/= biggest) biggestLength++; } //輸出部分 for (int i = 0; i < array.Length; i++) { Console.WriteLine($"當前時間:{i} \t 在線人數:{array[i]}"); } Console.WriteLine($"當天最大峰值:{biggest}人,開始時間:{biggestTime}點,持續時間:{biggestLength}h"); Console.ReadKey();
運行結果:

不知道大家看出來我們兩個邏輯上有什么不同嗎?
其實主要的不同是第一部分求每個小時在線人數的思路上的不同:
我的想法是輪詢24小時,遍歷log資料發現在遍歷的時間內就+1;
他的思路是遍歷log資料,在資料的開始結束時間內都+1,
他這樣做的話就在復雜度上少了很多,至少比我少一半的復雜度,
這其實就是一道大廠非常喜歡考的邏輯演算法的題目,我朋友這樣的演算法自然更好:邏輯清晰,復雜度低,
如果大家還有什么更好的解法歡迎寫在下面,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/270736.html
標籤:其他
上一篇:虛擬頭節點秒殺鏈表問題
下一篇:介面測驗斷言從哪些方面去設計?
