From 97dae3a1fd23062568163a073dab660870628f9c Mon Sep 17 00:00:00 2001 From: NobukiFukui Date: Sat, 29 Jun 2024 16:29:38 +0900 Subject: [PATCH 1/3] Q2-06-1st_2nd --- md/2-06_MajorityElement.md | 55 ++++++++++++++++++++++++++++++++++ python/2-06_MajorityElement.py | 18 +++++++++++ 2 files changed, 73 insertions(+) create mode 100644 md/2-06_MajorityElement.md create mode 100644 python/2-06_MajorityElement.py diff --git a/md/2-06_MajorityElement.md b/md/2-06_MajorityElement.md new file mode 100644 index 0000000..3d36246 --- /dev/null +++ b/md/2-06_MajorityElement.md @@ -0,0 +1,55 @@ +# 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): + return num +``` + +# 2nd +discord上のほかの議論を参照 +・Boyer-Moore majority vote algorithm +要素が同じであれば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 +``` \ No newline at end of file diff --git a/python/2-06_MajorityElement.py b/python/2-06_MajorityElement.py new file mode 100644 index 0000000..2f8a82b --- /dev/null +++ b/python/2-06_MajorityElement.py @@ -0,0 +1,18 @@ + +# %% +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)) +# %% From ed1a9e449bba3ba13f1314a25e7fde3c29524965 Mon Sep 17 00:00:00 2001 From: NobukiFukui Date: Sat, 29 Jun 2024 17:07:15 +0900 Subject: [PATCH 2/3] Q2-06-3rd --- md/2-06_MajorityElement.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/md/2-06_MajorityElement.md b/md/2-06_MajorityElement.md index 3d36246..c1beb94 100644 --- a/md/2-06_MajorityElement.md +++ b/md/2-06_MajorityElement.md @@ -52,4 +52,18 @@ class Solution: else: count -= 1 return majority_candidate -``` \ No newline at end of file +``` + +# 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 +``` From 0d1f4fda7dc9d732db2c039a1c5e5d3614fc9857 Mon Sep 17 00:00:00 2001 From: NobukiFukui Date: Sun, 30 Jun 2024 00:47:05 +0900 Subject: [PATCH 3/3] Q2-06-4th --- md/2-06_MajorityElement.md | 20 +++++++++++++++++ python/2-06_MajorityElement.py | 39 ++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/md/2-06_MajorityElement.md b/md/2-06_MajorityElement.md index c1beb94..b64e46c 100644 --- a/md/2-06_MajorityElement.md +++ b/md/2-06_MajorityElement.md @@ -67,3 +67,23 @@ class Solution: 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 +``` + diff --git a/python/2-06_MajorityElement.py b/python/2-06_MajorityElement.py index 2f8a82b..073d428 100644 --- a/python/2-06_MajorityElement.py +++ b/python/2-06_MajorityElement.py @@ -16,3 +16,42 @@ def majorityElement(self, nums: List[int]) -> int: 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}") \ No newline at end of file