알고리즘

분할 정복

jwjwvison 2022. 5. 21. 11:18

 분할 정복은 다중 분기 재귀를 기반으로 하는 알고리즘 디자인 패러다임을 말한다.

 

 분할 정복(Divide and Conquer)은 직접 해결할 수 있을 정도로 간단한 문제가 될 때까지 문제를 재귀적으로 쪼개나간 다음, 그 하위 문제의 결과들을 조합하여 원래 문제의 결과로 만들어 낸다. 대표적인 분할 정복 알고리즘은 병합 정렬을 들 수 있는데, 병합 정렬 과정을 표현한 그림은 다음과 같다.

 

https://leetcode.com/problems/majority-element/submissions/

 

Majority Element - LeetCode

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

 

 

 1. 부르트 포스로 과반수 비교

 앞에서 부터 하나씩 과반수를 넘는지 일일이 체크하다가 과반수를 넘으면 바로 정답으로 처리하면 된다.

class Solution:
    def majorityElement(self, nums: List[int]) -> int:
        for num in nums:
            if nums.count(num) > len(nums)//2:
                return num

 그러나 이 방법은 타임아웃이 발생한다.

 

 2. 다이나믹 프로그래밍

class Solution:
    def majorityElement(self, nums: List[int]) -> int:
        counts=collections.defaultdict(int)
        for num in nums:
            if counts[num] == 0:
                counts[num] = nums.count(num)
                
            if counts[num] > len(nums) //2:
                return num

 이 풀이는 메모이제이션을 이용한 매우 간단한 다이나믹 프로그래밍 풀이이다. 

 

 3. 분할 정복

 과반수 후보군에 해당하는 엘리멑느만 리턴하면서 다음 그림처럼 계속 위로 올려주면(즉, 백트래킹하면) 최종적으로 정답이 남게 된다.

class Solution:
    def majorityElement(self, nums: List[int]) -> int:
        if not nums:
            return None
        if len(nums) == 1:
            return nums[0]
        
        half=len(nums) // 2
        a=self.majorityElement(nums[:half])
        b=self.majorityElement(nums[half:])
        print(nums,a,b)
        return [b,a][nums.count(a) > half]

 

 4. 파이썬 다운 방식

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

 위 방법이 제일 빠르다.

'알고리즘' 카테고리의 다른 글

연속합 - 백준 1912번  (0) 2022.06.17
분할 정복 예제 ( 괄호를 삽입하는 여러가지 방법)  (0) 2022.05.21
그리디 알고리즘 예제  (0) 2022.05.19
그리디 알고리즘  (0) 2022.05.19
슬라이딩 윈도우  (0) 2022.05.17