-
Notifications
You must be signed in to change notification settings - Fork 0
Q2-6 Majority Element #34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| # 2-06 MajorityElement | ||
| Author: WaveAlchemist | ||
| URL: https://leetcode.com/problems/majority-element/description/ | ||
|
|
||
| Given an array nums of size n, return the majority element. | ||
| The majority element is the element that appears more than ⌊n / 2⌋ times. You may assume that the majority element always exists in the array. | ||
| Example 1: | ||
| Input: nums = [3,2,3] | ||
| Output: 3 | ||
|
|
||
| Example 2: | ||
| Input: nums = [2,2,1,1,1,2,2] | ||
| Output: 2 | ||
|
|
||
| # 1st | ||
| defaultdict nums_countを用いて,各要素の個数をカウント | ||
| 各要素の個数が過半数を超えた時点でその要素を返す | ||
| 所要時間 4min46s | ||
| 実行時間 172ms | ||
|
|
||
| ``` Python | ||
| class Solution: | ||
| def majorityElement(self, nums: List[int]) -> int: | ||
| # dictionary for counting numbers of each element | ||
| nums_count = defaultdict(int) | ||
| # count numbers contained in nums | ||
| for num in nums: | ||
| if not nums_count[num]: | ||
| nums_count[num] = 0 | ||
| nums_count[num] += 1 | ||
| if nums_count[num] > (len(nums) // 2): | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. こちら len()がどのくらいコスト掛かるかはみておいても良いと思いました。
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. コメントありがとうございます. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. はい、ガベージコレクションの実装によるとは思いますが結果を内部的に使いまわせるかは恐らくNOです。(numsの長さが変わらない保証がないため) 今回はここだけですが、近いコードを書くときに複数回len()を見たくなるケースが出てくるだろうという意味でも、ループ前に定義すると良いかと思います。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (お節介ですが念の為 実装するもの次第かなと There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. listに対するlenは定数時間ではないですか? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. すみません失礼、たしかに定数時間ですね。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 関数呼び出しのオーバーヘッドはあるでしょうが、私は len のほうが読みやすいと思います。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. こちらでも似たような議論が起きました! |
||
| return num | ||
| ``` | ||
|
|
||
| # 2nd | ||
| discord上のほかの議論を参照 | ||
| ・Boyer-Moore majority vote algorithm | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ありがとうございます. |
||
| 要素が同じであればcountに+1をし,そうでなければ-1を行う | ||
| 要素が過半数ない場合はcountが0をまたぐので,その時点で候補を変更する | ||
| https://leetcode.com/problems/majority-element/solutions/3676530/3-method-s-beats-100-c-java-python-beginner-friendly/ | ||
|
|
||
| ``` Python | ||
| class Solution: | ||
| def majorityElement(self, nums: List[int]) -> int: | ||
| count = 0 | ||
| majority_candidate = 0 | ||
| for num in nums: | ||
| if count == 0: | ||
| majority_candidate = num | ||
| if num == majority_candidate: | ||
| count += 1 | ||
| else: | ||
| count -= 1 | ||
| return majority_candidate | ||
| ``` | ||
|
|
||
| # 3rd | ||
| ・kitakenさんのご指摘 | ||
| defaultdictの場合はこの場合分け不要 | ||
|
|
||
| ``` Python | ||
| class Solution: | ||
| def majorityElement(self, nums: List[int]) -> int: | ||
| num_count = defaultdict(int) | ||
| for num in nums: | ||
| num_count[num] += 1 | ||
| if num_count[num] > len(nums) // 2: | ||
| return num | ||
| ``` | ||
| # 4th | ||
| ・kouさんのコメント | ||
| こちら len()がどのくらいコスト掛かるかはみておいても良いと思いました。 | ||
| ループの中で使うより先に定義して置く方が良いと思います | ||
| ⇒ | ||
| timeitを用いて調べると以下のように実行時間に差が出現. | ||
| 事前定義をする場合 time: 0.7654874669999856 | ||
| 事前定義をしない場合 time: 0.9718373919999976 | ||
|
|
||
| ``` Python | ||
| class Solution: | ||
| def majorityElement(self, nums: List[int]) -> int: | ||
| nums_count = defaultdict(int) | ||
| nums_length = len(nums) | ||
| for num in nums: | ||
| nums_count[num] += 1 | ||
| if nums_count[num] > nums_length // 2: | ||
| return num | ||
| ``` | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
|
|
||
| # %% | ||
| class Solution: | ||
| def majorityElement(self, nums: List[int]) -> int: | ||
| # dictionary for counting numbers of each element | ||
| nums_count = defaultdict(int) | ||
| # count numbers contained in nums | ||
| for num in nums: | ||
| if not nums_count[num]: | ||
| nums_count[num] = 0 | ||
| nums_count[num] += 1 | ||
| if nums_count[num] > (len(nums) // 2): | ||
| return num | ||
|
|
||
| solution = Solution() | ||
| nums = [1,2,2,2,1] | ||
| print(solution.majorityElement(nums)) | ||
| # %% | ||
| import timeit | ||
| from collections import defaultdict | ||
| from typing import List | ||
|
|
||
| class Solution1: | ||
| def majorityElement(self, nums: List[int]) -> int: | ||
| num_count = defaultdict(int) | ||
| length_num = len(nums) | ||
| for num in nums: | ||
| num_count[num] += 1 | ||
| if num_count[num] > length_num // 2: | ||
| return num | ||
|
|
||
| class Solution2: | ||
| def majorityElement(self, nums: List[int]) -> int: | ||
| num_count = defaultdict(int) | ||
| for num in nums: | ||
| num_count[num] += 1 | ||
| if num_count[num] > len(nums) // 2: | ||
| return num | ||
|
|
||
| # テストデータを用意 | ||
| test_data = [3, 2, 3, 1, 3, 4, 3, 3] | ||
|
|
||
| # 計測対象の関数を呼び出すラッパー関数を定義 | ||
| def test_solution1(): | ||
| solution = Solution1() | ||
| return solution.majorityElement(test_data) | ||
|
|
||
| def test_solution2(): | ||
| solution = Solution2() | ||
| return solution.majorityElement(test_data) | ||
|
|
||
| # timeitを使用して実行時間を計測 | ||
| time_solution1 = timeit.timeit(test_solution1, number=100000) | ||
| time_solution2 = timeit.timeit(test_solution2, number=100000) | ||
|
|
||
| print(f"Solution1 time: {time_solution1}") | ||
| print(f"Solution2 time: {time_solution2}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
defaultdictの場合はこの場合分け不要
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ありがとうございます.
https://docs.python.org/ja/3.6/library/collections.html#defaultdict-examples
には
それぞれのキーが最初に登場したとき、マッピングにはまだ存在しません。そのためエントリは default_factory 関数が返す空の list を使って自動的に作成されます。
とありますね