🙄
100日アルゴリズム[20日目・ユーザーごとのカウント]
解いた問題
解法
あまり綺麗に書けなかった。コードはパスするが、もっといい対処法がありそう。
function countMentions(numberOfUsers: number, events: string[][]): number[] {
type UserStatus = {
calledCount: number;
isOnline: boolean;
offlineTimeStamp: number;
};
// 初期化: 各ユーザーの状態を保持するマップを作成
const userStatusMap = new Map<number, UserStatus>();
for (let i = 0; i < numberOfUsers; i++) {
userStatusMap.set(i, {
calledCount: 0,
isOnline: true,
offlineTimeStamp: -1,
});
}
// イベントをソートする
const sortedEvents = [...events].sort((a, b) => {
const timeA = Number(a[1]);
const timeB = Number(b[1]);
if (timeA !== timeB) {
return timeA - timeB;
}
// 同じタイムスタンプの場合、OFFLINEを先に処理
return a[0] === "OFFLINE" ? -1 : b[0] === "OFFLINE" ? 1 : 0;
});
// イベント処理
for (const event of sortedEvents) {
const [eventType, timestampStr, eventData] = event;
const timestamp = Number(timestampStr);
if (eventType === "OFFLINE") {
// OFFLINEイベントの場合、指定されたユーザーをオフラインにする
const userId = Number(eventData);
const userStatus = userStatusMap.get(userId)!;
userStatus.isOnline = false;
userStatus.offlineTimeStamp = timestamp;
} else if (eventType === "MESSAGE") {
// MESSAGEイベントの場合、メッセージの対象ユーザーを処理
const mentionedUsers = eventData.split(" ");
for (const mentioned of mentionedUsers) {
if (mentioned === "ALL") {
// 全ユーザーを言及
for (const [userId, userStatus] of userStatusMap.entries()) {
userStatus.calledCount++;
}
} else if (mentioned === "HERE") {
// オンラインユーザーを言及
for (const [userId, userStatus] of userStatusMap.entries()) {
if (
userStatus.isOnline ||
timestamp - userStatus.offlineTimeStamp >= 60
) {
userStatus.calledCount++;
}
}
} else if (mentioned.startsWith("id")) {
// 特定のユーザーを言及
const userIds: number[] = mentioned
.replace("id", "")
.split(" ")
.map(Number);
for (const userId of userIds) {
const userStatus = userStatusMap.get(userId)!;
userStatus.calledCount++;
}
}
}
}
}
// 結果を返す
const result: number[] = [];
for (let i = 0; i < numberOfUsers; i++) {
result.push(userStatusMap.get(i)!.calledCount);
}
return result;
}
以下に計算量など記述しました。
Discussion