Skip to content

Conversation

@argondev22
Copy link
Owner

@argondev22 argondev22 commented Oct 23, 2025

Status

Accepted

Time Taken

1 h 20 m 22 s

…eScript, including in-place modification of nums1 and a sorting algorithm. Status and time taken comments included for reference.
@argondev22 argondev22 requested a review from Copilot October 23, 2025 23:10
@argondev22 argondev22 self-assigned this Oct 23, 2025
@argondev22 argondev22 linked an issue Oct 23, 2025 that may be closed by this pull request
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

あなたの解答を評価させていただきます!

📊 総合評価:4点 / 10点

良い点(+4点)

  1. ✓ 正しく動作する(+2点)

    • ロジックは正確で、期待通りの結果が得られます
    • In-place修正の要件を満たしています
  2. ✓ コードが読みやすい(+1点)

    • 変数名が明確(preElement, postElement
    • 処理の流れが直感的
  3. ✓ 基本的なアプローチ(+1点)

    • まずマージ、次にソートという考え方は理解しやすい

改善が必要な点(-6点)

1. 時間計算量が非効率(-3点)

// あなたのコード:O((m+n)²) - バブルソート
for (let i = 0; i < m + n; i++) {           // O(m+n)
    for (let j = 0; j < m + n; j++) {       // O(m+n)
        // 交換処理
    }
}

問題点:

  • ネストしたループで O((m+n)²) の時間計算量
  • 両配列がすでにソート済みという重要な情報を活用していない
  • 大きなデータセットでは非常に遅い

2. バブルソートの実装ミス(-2点)

for (let i = 0; i < m + n; i++) {
    for (let j = 0; j < m + n; j++) {  // ❌ ここが問題

問題点:

  • 内側のループが m + n - 1 まで実行すべき
  • j + 1 が配列外を参照する可能性がある
  • たまたま動いているが、バグの原因になりうる

3. 最適解からかけ離れている(-1点)

  • この問題は O(m+n) で解ける典型問題
  • ソート済み配列の特性を活かすべき

🎯 最適解(2ポインタ手法)

function merge(nums1: number[], m: number, nums2: number[], n: number): void {
    // 後ろから埋めていく(上書きを避けるため)
    let i = m - 1;      // nums1の有効要素の最後尾
    let j = n - 1;      // nums2の最後尾
    let k = m + n - 1;  // 結果配列の最後尾

    // 両方の配列に要素が残っている間
    while (i >= 0 && j >= 0) {
        if (nums1[i] > nums2[j]) {
            nums1[k] = nums1[i];
            i--;
        } else {
            nums1[k] = nums2[j];
            j--;
        }
        k--;
    }

    // nums2に残りがあれば埋める
    while (j >= 0) {
        nums1[k] = nums2[j];
        j--;
        k--;
    }
    // nums1の残りは既に正しい位置にあるので処理不要
}

📈 計算量の比較

解法 時間計算量 空間計算量 評価
あなたの解答 O((m+n)²) O(1) ❌ 非効率
最適解 O(m+n) O(1) ✅ 最適

具体例で比較

m = 100, n = 100 の場合
- あなたの解法:約 40,000回 の比較・交換
- 最適解:約 200回 の比較・代入
→ 200倍の差!

💡 改善アドバイス

1. 問題の制約を見逃さない

"sorted in non-decreasing order"(ソート済み)

この情報が最も重要なヒントです!

2. 後ろから埋める発想

// ❌ 前から埋めると上書きの危険
[1, 2, 3, 0, 0, 0]  前から埋めると1,2,3が消える

// ✅ 後ろから埋めると安全
[1, 2, 3, 0, 0, 0]  後ろは空いているので安全

3. 2ポインタ手法を学ぶ

この問題は2ポインタ手法の典型例です:

  • ポインタ1: nums1の末尾
  • ポインタ2: nums2の末尾
  • ポインタ3: 書き込み位置

🔧 あなたのコードの修正版

もし現在のアプローチを改善するなら:

function merge(nums1: number[], m: number, nums2: number[], n: number): void {
    // Step 1: nums2をnums1の後ろにコピー
    for (let i = 0; i < n; i++) {
        nums1[m + i] = nums2[i];
    }

    // Step 2: バブルソートを修正
    for (let i = 0; i < m + n - 1; i++) {  // -1を追加
        for (let j = 0; j < m + n - 1 - i; j++) {  // 最適化
            if (nums1[j] > nums1[j + 1]) {
                // 交換(分割代入を使用)
                [nums1[j], nums1[j + 1]] = [nums1[j + 1], nums1[j]];
            }
        }
    }
}

ただし、これでも O((m+n)²) なので最適解には劣ります。

📚 学習のヒント

  1. ソート済み配列の問題 → 2ポインタを検討
  2. In-place操作 → 後ろから処理を検討
  3. 時間計算量を意識 → ネストループは避ける

頑張ってください!次は最適解に挑戦してみてくださいね! 🚀

Comment on lines +9 to +17
for (let i = 0; i < m + n; i++) {
for (let j = 0; j < m + n; j++) {
const preElement = nums1[j];
const postElement = nums1[j + 1];
if (preElement > postElement) {
nums1[j] = postElement;
nums1[j + 1] = preElement;
}
}
Copy link

Copilot AI Oct 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

現在の実装はバブルソートを使用しており、時間計算量がO((m+n)²)となっています。「Merge Sorted Array」問題では、両方の配列が既にソート済みであるという特性を活かすべきです。推奨される解法は、2つのポインタを使って後ろから要素を配置していく方法で、時間計算量O(m+n)、空間計算量O(1)で実現できます。\n\n改善案:\ntypescript\nexport function merge(nums1: number[], m: number, nums2: number[], n: number): void {\n let i = m - 1; // nums1の最後の有効要素\n let j = n - 1; // nums2の最後の要素\n let k = m + n - 1; // nums1の最後の位置\n \n while (j >= 0) {\n if (i >= 0 && nums1[i] > nums2[j]) {\n nums1[k] = nums1[i];\n i--;\n } else {\n nums1[k] = nums2[j];\n j--;\n }\n k--;\n }\n}\n\nこの解法により、既にソート済みという特性を活用して効率的にマージできます。

Copilot generated this review using guidance from repository custom instructions.
}

for (let i = 0; i < m + n; i++) {
for (let j = 0; j < m + n; j++) {
Copy link

Copilot AI Oct 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

配列の境界チェックが不足しています。jm + n - 1の時にnums1[j + 1]にアクセスすると、配列の範囲外を参照することになります。ループ条件をj < m + n - 1に変更するか、アクセス前に境界チェックを追加する必要があります。\n\n改善案:\ntypescript\nfor (let j = 0; j < m + n - 1; j++) {\n const preElement = nums1[j];\n const postElement = nums1[j + 1];\n if (preElement > postElement) {\n nums1[j] = postElement;\n nums1[j + 1] = preElement;\n }\n}\n

Suggested change
for (let j = 0; j < m + n; j++) {
for (let j = 0; j < m + n - 1; j++) {

Copilot uses AI. Check for mistakes.
@argondev22 argondev22 moved this to Doing in My Learnings Oct 23, 2025
@argondev22 argondev22 merged commit 166a279 into main Oct 23, 2025
@argondev22 argondev22 deleted the 20251023-88-merge-sorted-array branch October 23, 2025 23:13
@github-project-automation github-project-automation bot moved this from Doing to Done in My Learnings Oct 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

88. Merge Sorted Array

2 participants