Home [LeetCode解法] 27. Remove Element
Post
Cancel

[LeetCode解法] 27. Remove Element

問題の説明

LeetCode 27. Remove Element

指定された値(val)をリストから削除し、残った要素の数を算出するアルゴリズムです。

解法

アプローチ 1.

1) valがnumsにある限りnumsを走査して削除します。 2) 削除と同時に末尾に _ を追加します。 3) 発見するたびにcntを増やし、これを元の長さから引いて返します。

1
2
3
4
5
6
7
8
9
class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        org_len = len(nums)
        cnt = 0
        while val in nums:
            nums.remove(val)
            nums.append("_")
            cnt += 1
        return org_len - cnt

上記解法の時間複雑度と空間複雑度は次の通りです。

  • 時間複雑度: O(N^2)
    • remove関数の時間複雑度がO(N)であり、これをnumsの要素数だけ繰り返すためO(N^2)の時間複雑度がかかります。
  • 空間複雑度: O(1)
    • 単純ないくつかの変数しか使用していないため、O(1)です。

この方法は時間複雑度がO(N^2)であるため、入力が多くなると実行時間が長くなり、タイムアウトの可能性が高いです。

アプローチ 2. Two Pointer

Two Pointerを使用して、左右の2つのインデックスを調整しながら重複した値を削除しました。 1) leftとrightという2つのインデックスを0から始め、 2-1) rightがvalの場合、_に変換し、rightは1つ右に移動します。 2-2) rightがvalでない場合、leftとrightを交換し、両方とも1つずつ同時に移動します。

このロジックに従うと、3223という入力で3を削除する場合、以下のフローになります。

1
2
3
4
5
3223
_223    <- rightが3なので_に変更し、rightは1つ右に移動
2_23    <- leftとrightが異なるので
22_3    <- 2つの値を交換
22__    <- rightが3なので_に変更
1
2
3
4
5
6
7
8
9
10
11
12
class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        left, right = 0, 0
        while right < len(nums):
            if nums[right] == val:
                nums[right] = '_'
                right += 1
            else: 
                nums[left], nums[right] = nums[right], nums[left]
                left += 1 
                right += 1
        return left
  • 時間複雑度: O(N)
    • numsのサイズだけ時間がかかります。
  • 空間複雑度: O(1)
    • 単純ないくつかの変数しか使用していないため、O(1)です。
This post is licensed under CC BY 4.0 by the author.