문제는 다음과 같습니다.
쉽지만, 새로운 알고리즘을 배울 수 있었던 문제였습니다.
➡️ 가장 마지막 풀이에 소개하겠습니다.
총 3가지 방법으로 풀었는데, 다음과 같습니다.
1. hash 이용
key에 해당 숫자와, value에 해당 숫자가 나온 횟수를 계산하여,
hash map의 value중 최댓값을 구해주면 됩니다.
전체 코드는 다음과 같습니다.
class Solution {
public:
int majorityElement(vector<int>& nums) {
unordered_map<int, int> um;
for(int i=0; i<nums.size(); i++) um[nums[i]]++;
int key=0, val=0;
for(auto a: um){
if(a.second>val){ key=a.first; val=a.second; }
}
return key;
}
};
2. sort
문제를 잘 읽어보면, 가장 많이 나온 수는 전체 수의 절반이상으로 나온다고 합니다.
(The majority element is the element that appears more than ⌊n / 2⌋ times.)
따라서 정렬을 수행한 뒤, 벡터의 절반에 위치한 원소는 항상 전체 벡터 원소 중 가장 많은 빈도수의 원소입니다.
class Solution {
public:
int majorityElement(vector<int>& nums) {
sort(nums.begin(), nums.end());
return nums[nums.size()/2];
}
};
3. Boyer-Moore algorithm(보이어 무어 알고리즘)
이 풀이는 discussion에서 가장 많은 투표수를 얻은 풀이를 제가 조금 제 방식으로 다듬은 풀이입니다.
해당 풀이에서 사용한 알고리즘은 Boyer Moore 알고리즘으로, 주로 문자열 검색 알고리즘에서 쓰인다고 합니다.
문자열 문제를 풀때, 이 알고리즘과 KMP는 꼭 정리해두도록 하겠습니다.😊
✏️원리는 다음과 같습니다.✏️
임의로 첫 원소를 val에 저장하고, cnt는 카운트를 해주는 변수입니다. 처음엔 1로 시작합니다.
이후, 벡터의 두번째원소부터 끝까지 돌면서,
이때, for문의 가장 위에 오는 if문은 다음과 같습니다.
if(cnt==0) val=nums[i];
cnt==0 이라는 것은, 기존의 가장 많이 나왔던 원소와 같은 빈도수의 원소가 있다는 것입니다.
이 경우에는 val의 값을 현재 원소로 대체하면 됩니다.
이 원리로 끝까지 원소를 검사하면 됩니다.
전체 코드는 다음과 같습니다.
class Solution {
public:
int majorityElement(vector<int>& nums) {
int val=nums[0]; int cnt=1;
for(int i=1; i<nums.size(); i++){
if(cnt==0) val=nums[i];
if(val==nums[i]) cnt++;
else cnt--;
}
return val;
}
};