Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions src/leetcode/283_move-zeroes/20251209.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class Solution {
public void moveZeroes(int[] nums) {
int j = 0;

for (int i = 0; i < nums.length; i++) {
if (nums[i] == 0) {
continue;
}

int tmp = nums[j];
nums[j] = nums[i];
nums[i] = tmp;

Comment thread
argondev22 marked this conversation as resolved.
j++;
Comment on lines +3 to +14
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

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

変数名jが不明確です。この変数は非ゼロ要素を配置する位置を追跡するため、insertPosnonZeroIndexのようなより説明的な名前を使用することをお勧めします。

改善案:

int insertPos = 0;  // 非ゼロ要素を配置する位置
Suggested change
int j = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] == 0) {
continue;
}
int tmp = nums[j];
nums[j] = nums[i];
nums[i] = tmp;
j++;
int insertPos = 0; // 非ゼロ要素を配置する位置
for (int i = 0; i < nums.length; i++) {
if (nums[i] == 0) {
continue;
}
int tmp = nums[insertPos];
nums[insertPos] = nums[i];
nums[i] = tmp;
insertPos++;

Copilot uses AI. Check for mistakes.
}
}
}
Comment on lines +1 to +17
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

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

📊 総合評価:8点 / 10点

良い点(+8点)

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

  • アルゴリズムは正確で、全てのテストケースで期待通りの結果を出力します
  • 非ゼロ要素の相対的な順序を保持しながら、ゼロを配列の末尾に移動しています
  • 例: [0,1,0,3,12][1,3,12,0,0] が正しく動作

2. 効率的な実装(+3点)

  • 時間計算量: O(n) - 配列を1回だけトラバース
  • 空間計算量: O(1) - 追加の配列を使用せず、in-placeで操作
  • 2ポインタ方式で効率的に実装されています

3. 簡潔な実装(+2点)

  • コードが短く、理解しやすい構造
  • 不要な処理を避けている

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

1. 変数名の不明確さ(-1点)

問題点: 変数jの役割が一目で分かりにくい

int j = 0;  // 何のインデックスか不明確

改善案:

int insertPos = 0;  // 非ゼロ要素を配置する位置
// または
int nonZeroIndex = 0;  // 次の非ゼロ要素の挿入位置

2. 不要なスワップ処理(-1点)

問題点: i == jの場合、自分自身とスワップする無駄な処理が発生

// i == j の場合、以下は不要
int tmp = nums[j];
nums[j] = nums[i];
nums[i] = tmp;

改善案:

if (nums[i] != 0) {
    if (i != j) {  // i != j の場合のみスワップ
        int tmp = nums[j];
        nums[j] = nums[i];
        nums[i] = tmp;
    }
    j++;
}

🎯 最適解との比較

推奨解法(改善版)

class Solution {
    public void moveZeroes(int[] nums) {
        int insertPos = 0;  // より明確な変数名
        
        // 非ゼロ要素を前に詰める
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] != 0) {
                if (i != insertPos) {  // 不要なスワップを避ける
                    nums[insertPos] = nums[i];
                    nums[i] = 0;
                }
                insertPos++;
            }
        }
    }
}

メリット:

  • ✅ 変数名がより分かりやすい(insertPosは非ゼロ要素の挿入位置を明示)
  • i == insertPosの場合の不要なスワップを回避
  • ✅ スワップではなく直接代入することで、よりシンプル

📊 計算量の比較

解法 時間計算量 空間計算量 不要な処理
現在の解法 O(n) O(1) i==jの場合の無駄なスワップあり
推奨解法 O(n) O(1) 不要な処理を回避

💡 学習ポイント

1. 2ポインタ方式の理解

  • i: 配列全体を走査するポインタ
  • j (または insertPos): 非ゼロ要素を配置する位置を追跡

2. 変数命名の重要性

  • jよりもinsertPosnonZeroIndexの方が意図が明確
  • 可読性の向上はバグの削減につながる

3. エッジケースの確認

  • 全てゼロの配列: [0,0,0] → 正しく動作 ✅
  • ゼロがない配列: [1,2,3] → 正しく動作(ただし不要なスワップが発生)
  • 単一要素: [0] または [1] → 正しく動作 ✅

📝 まとめ

良かった点

  • ✅ アルゴリズムの正しさ:完璧に動作
  • ✅ 時間・空間計算量:最適なO(n)とO(1)
  • ✅ in-place操作:追加のメモリを使用しない

改善点

  • ❌ 変数名:jinsertPosなどに変更すると可読性向上
  • ❌ 最適化:i == jの場合の不要なスワップを回避

次のステップ

  1. 変数名をより説明的なものに変更する
  2. 不要な処理を削減する条件分岐を追加
  3. 他の2ポインタ問題(例:Remove Duplicates from Sorted Array)にも挑戦

全体的に非常に良い実装です! アルゴリズムの核心を理解しており、効率的なソリューションを実装できています。細かい最適化と可読性の向上で、さらに優れたコードになります。引き続き頑張ってください!🎉

Copilot generated this review using guidance from repository custom instructions.