アルゴリズム概要

問題説明

正の整数 millis を受け取り、その時間(ミリ秒)だけ非同期にスリープする関数を実装します。実際のスリープ時間が millis から若干ずれても許容されます。

入出力例

例1:

Input: millis = 100
Output: 100
Explanation: 100msスリープ後に完了する

例2:

Input: millis = 200
Output: 200
Explanation: 200msスリープ後に完了する

制約条件

戦略

主要ポイント

時間計算量: O(1) - 定数時間での処理開始

空間計算量: O(1) - Promiseオブジェクト1つのみ

最適化手法: 外部ライブラリ不要、標準API のみ使用

ステップバイステップ解説

TypeScript実装

/**
 * 指定されたミリ秒数だけ非同期にスリープする関数
 * @param millis - 待機するミリ秒数(1-1000)
 * @returns void を解決するPromise
 * @complexity Time: O(1), Space: O(1)
 */
async function sleep(millis: number): Promise<void> {
    // Promiseでラップした setTimeout による非同期待機
    return new Promise<void>((resolve) => {
        setTimeout(resolve, millis);
    });
}

/**
 * 使用例
 */
let t = Date.now();
sleep(100).then(() => {
    console.log(Date.now() - t); // ~100
});

エラーハンドリング付き実装

async function sleep(millis: number): Promise<void> {
    // 型ガード: 数値チェック
    if (typeof millis !== 'number' || Number.isNaN(millis)) {
        throw new TypeError('millis must be a valid number');
    }

    // 範囲チェック(制約条件: 1 <= millis <= 1000)
    if (millis < 1 || millis > 1000) {
        throw new RangeError('millis must be between 1 and 1000');
    }

    // 整数チェック(正の整数要件)
    if (!Number.isInteger(millis)) {
        throw new RangeError('millis must be an integer');
    }

    // Promise でラップした setTimeout による非同期待機
    return new Promise<void>((resolve) => {
        setTimeout(resolve, millis);
    });
}

フローチャート

計算量分析

項目 計算量 説明
時間計算量 O(1) Promise作成とsetTimeoutスケジューリングは定数時間
空間計算量 O(1) Promiseオブジェクトとクロージャのみ
実際の待機時間 O(millis) 実時間だが計算量ではない(CPU処理時間は無し)

実装手法の比較

手法 時間 空間 CPU使用率 推奨度
Promise + setTimeout O(1) O(1) 0%(非ブロッキング) ⭐⭐⭐⭐⭐
Busy Wait(while loop) O(millis) O(1) 100%(ブロッキング) ✗ 非推奨
setInterval + clearInterval O(1) O(1) 0%(非ブロッキング) ⭐⭐ 不要な複雑性

✅ 推奨: Promise + setTimeout

最もシンプルで効率的。イベントループをブロックせず、他のタスクが並行実行可能。