10月16日開催!現年収非公開で企業からスカウトをもらってみませんか?PR

転職ドラフトでリアルな市場価値を測る。レジュメをもとに、企業から年収とミッションが提示されます。

1
0

多数派要素の取得 Python

Posted at

はじめに

LeetCodeで出題された内容から、調べたことを自分用の備忘録として残しています。

多数派要素とは

全体の要素の半数以上(つまり、全体の要素数の半分を超える)登場する要素

具体例:

リスト: [3, 2, 3]
このリストには3つの要素があり、それぞれの登場回数は次の通りです。

  • 3 が2回登場
  • 2 が1回登場
    この場合、リストに含まれる要素の数が3つなので、その半数は 3 ÷ 2 = 1.5 です。これを切り上げた数の 2回以上登場する要素が多数派要素です。この場合、3 が2回登場しているため、3 が多数派要素になります。

多数派要素の取得アルゴリズム

ボイヤー・ムーアの多数決アルゴリズムを使う方法

私がまっさきに考えたのが、この方法です。

class Solution:
    def majorityElement(self, nums: List[int]) -> int:
        candidate = None
        count = 0

        for num in nums:
            if count == 0:
                candidate = num
            if num == candidate:
                count += 1
            else:
                count -=1
        return candidate

時間計算量:O(n)
配列を1回だけ走査するため。

Pythonのcollections.Counterクラスを使った方法

collections.Counterクラスと組み込み関数maxを使うとより簡潔なコードが書けます。
時間計算量は、多数決アルゴリズムと変わりません。

class Solution:
    def majorityElement(self, nums: List[int]) -> int:
        a=Counter(nums)
        return max(a, key=a.get)

時間計算量:O(n)
collections.Counterの計算量、maxの計算量ともにO(n)のため。

参考サイト
https://qiita.com/ell/items/259388b511e24625c0d7
https://qiita.com/Hironsan/items/68161ee16b1c9d7b25fb

ドキュメント
https://docs.python.org/ja/3/library/collections.html#collections.Counter
https://docs.python.org/ja/3/library/functions.html#max

昇順にソートして中央値の要素を返す

簡潔なコードで書ける上に、先の2つの方法よりも速く処理ができます。
スマートな方法と感動しました!

class Solution:
    def majorityElement(self, nums: List[int]) -> int:
        nums.sort()
        return nums[len(nums) // 2]

時間計算量:O(n log n)(n はリストの要素数)

  • nums.sort() の計算量:
    sort() は内部的に「Timsort」というアルゴリズムを使用しており、平均・最悪の場合でも O(n log n) です。ここで、n は nums の要素数です。
  • nums[len(nums) // 2] の計算量:
    リストの中央の要素にアクセスする操作は定数時間(O(1))で行えます。

最後まで読んでくださって、ありがとうございます。誤り等あれば、ご指摘くださるとありがたいです。

1
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up

Comments

zacky1972
@zacky1972(山崎 進)

O(n) と O(nlogn) だと、後者の方が遅いと思います。

Boyer-Mooreのアルゴリズムについては、書かれたプログラムだと、過半数が決まらなかった時に結果が不定になる不具合があると思います。オリジナルの論文を読んだら、その問題を解消するようにできていました。下記の記事に Elixir でのプログラム例ではありますが、記述していますので、参考にされてください。

0

Let's comment your feelings that are more than good

Being held Article posting campaign

1
0

Login to continue?

Login or Sign up with social account

Login or Sign up with your email address