Skip to content

Conversation

@argondev22
Copy link
Owner

@argondev22 argondev22 commented Oct 29, 2025

Status

Accepted

Runtime

0 ms

Memory

6.24 MB

Time Taken

9 m 46 s

Implement function to remove duplicates from sorted array.
@argondev22 argondev22 self-assigned this Oct 29, 2025
Copilot AI review requested due to automatic review settings October 29, 2025 07:33
@argondev22 argondev22 linked an issue Oct 29, 2025 that may be closed by this pull request
@argondev22 argondev22 moved this to Doing in My Learnings Oct 29, 2025
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.

問題内容を確認しました。それでは、あなたの解答を詳しく評価いたします。


📊 総合評価:8.5点 / 10点


✅ 良い点

  1. 正しいアルゴリズム: Two-pointer手法を正しく実装しており、問題の要件を満たしています。
  2. 適切なエッジケース処理: 空配列のチェック(len(nums) == 0)を最初に行っています。
  3. In-place操作: 追加のメモリを使わず、元の配列を直接変更しています。
  4. 読みやすいコード: 変数名が明確で、ロジックが理解しやすい構造になっています。
  5. 正しい返り値: ユニークな要素の個数 k を正しく返しています。

⚠️ 改善が必要な点

  1. 不要なエッジケースチェック: 問題の制約条件に 1 <= nums.length とあるため、空配列のチェックは不要です(ただし、防御的プログラミングとしては有効)。

  2. 微細な非効率性: len(nums) - 1 をループ内で毎回評価しています(Go言語のコンパイラが最適化する可能性はありますが)。

  3. より直感的なアプローチの余地: 現在のコードは正しいですが、「次の異なる要素を見つけたら配置する」という考え方よりも、「現在の要素が前の要素と異なれば配置する」という考え方の方がより自然です。


🏆 最適解との比較

あなたのアプローチ

// 「次の要素が現在の要素と異なる」をチェック
if nums[i] != nums[i + 1] {
    nums[k] = nums[i + 1]
    k++
}

より標準的なアプローチ

// 「現在の要素が前の要素と異なる」をチェック
for i := 1; i < len(nums); i++ {
    if nums[i] != nums[i - 1] {
        nums[k] = nums[i]
        k++
    }
}

違い:

  • あなたのコード: ii+1 を比較(前向き比較)
  • 標準的なコード: ii-1 を比較(後ろ向き比較)

両方とも正解ですが、標準的なアプローチの方が「現在処理している要素」に焦点を当てているため、より直感的です。


⏱️ 計算量の比較

項目 あなたのコード 最適解
時間計算量 O(n) O(n)
空間計算量 O(1) O(1)

結論: 計算量は最適です!どちらも配列を一度だけ走査し、追加メモリを使用していません。


🔧 あなたのコードの具体的な改善

改善版1: より標準的なアプローチ

func removeDuplicates(nums []int) int {
    if len(nums) == 0 {
        return 0
    }
    
    k := 1
    
    for i := 1; i < len(nums); i++ {
        if nums[i] != nums[i-1] {
            nums[k] = nums[i]
            k++
        }
    }
    
    return k
}

改善版2: よりシンプル(エッジケース省略)

func removeDuplicates(nums []int) int {
    if len(nums) <= 1 {
        return len(nums)
    }
    
    k := 1
    
    for i := 1; i < len(nums); i++ {
        if nums[i] != nums[i-1] {
            nums[k] = nums[i]
            k++
        }
    }
    
    return k
}

改善版3: 最もシンプル(制約条件を信頼)

func removeDuplicates(nums []int) int {
    k := 1
    
    for i := 1; i < len(nums); i++ {
        if nums[i] != nums[i-1] {
            nums[k] = nums[i]
            k++
        }
    }
    
    return k
}

📚 学習ポイント

1. Two-Pointer テクニック

このアルゴリズムはTwo-Pointerパターンの典型例です:

  • 読み取りポインタ (i): 配列を順次走査
  • 書き込みポインタ (k): ユニークな要素を配置する位置

2. In-place アルゴリズム

追加のメモリを使わずに配列を変更する技術は、空間計算量を最適化する重要なテクニックです。

3. ソート済み配列の特性

ソート済み配列では、重複要素は必ず隣接しているため、O(n)の一度の走査で重複を検出できます。

4. エッジケースの判断

  • 問題の制約条件を確認し、必要なエッジケース処理を判断する
  • 過剰な防御的プログラミングは可読性を下げることもある

5. 前向き vs 後ろ向き比較

  • 前向き (nums[i] != nums[i+1]): 次を見る
  • 後ろ向き (nums[i] != nums[i-1]): 前を見る

どちらも有効ですが、「現在処理中の要素」に焦点を当てる後ろ向き比較の方が直感的です。


📝 まとめ

あなたの解答は非常に優れています。アルゴリズムの本質を理解し、正しく実装できています。

強み:

  • ✅ 正しいTwo-Pointerアプローチ
  • ✅ 最適な時間・空間計算量
  • ✅ 読みやすいコード

さらなる向上のために:

  • 🔄 標準的なパターン(後ろ向き比較)にも慣れる
  • 📋 問題の制約条件を活用し、不要なチェックを減らす
  • 💡 同じ問題に対する複数のアプローチを学ぶ

このレベルの理解があれば、類似の配列操作問題(例: Remove Element, Move Zeros)にも応用できます。引き続き頑張ってください! 🚀

Comment on lines +8 to +9
for i := 0; i < len(nums) - 1; i++ {
if nums[i] != nums[i + 1] {
Copy link

Copilot AI Oct 29, 2025

Choose a reason for hiding this comment

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

より効率的なアプローチとして、ii+1を比較するのではなく、kとの比較を行う方法があります。これにより、ループの範囲もlen(nums)全体に拡張でき、ロジックがよりシンプルになります。

推奨解法:

k := 1
for i := 1; i < len(nums); i++ {
if nums[i] != nums[k-1] {
nums[k] = nums[i]
k++
}
}

メリット:

  • ✅ インデックス計算(i+1)が不要になり、可読性が向上
  • ✅ ループ範囲が0からlen(nums)-1ではなく1からlen(nums)-1となり、意図がより明確

Copilot generated this review using guidance from repository custom instructions.
@argondev22 argondev22 merged commit 3ed5b1f into main Oct 29, 2025
6 checks passed
@argondev22 argondev22 deleted the 20251029/6-26-remove-duplicates-from-sorted-array branch October 29, 2025 07:38
@github-project-automation github-project-automation bot moved this from Doing to Done in My Learnings Oct 29, 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.

26. Remove Duplicates from Sorted Array

2 participants