분할정복 사용해 배열에서 과반수 요소 찾기

Haechan Kim·2021년 10월 10일
0

알고리즘

목록 보기
11/27

정수 배열에서 과반보다 많이 존재하는 요소를 찾는 알고리즘이다. 분할 정복을 이용하면 O(n log n)의 시간에 해결할 수 있다. 배열에 과반수 요소가 있다고 가정한다. 있을 지 없을지 모른다고 할때는 반복문을 한번 돌리면서 결과로 나온 숫자가 몇번 나오는지 보면 된다.
메인 아이디어는 배열을 계속 반으로 쪼개면서(logn) 양쪽 배열 각각의 과반수 원소를 찾는다(left, right). 배열을 다시 합치고 그 중 각 배열에서 더 많이 나온 요소가 전체 배열의 과반수 요소가 된다.
https://leetcode.com/problems/majority-element/
https://www.geeksforgeeks.org/majority-element/


public class Main
{/* 배열에서 과반수 요소를 찾아 리턴하는 함수
분할 정복을 사용해 배열을 반씩 나눠서 각 왼, 오른쪽 배열의
과반수 요소를 찾고 비교한다. */
    public static int maj(int[] arr, int start, int end)
    {
        if (start == end) // 배열에 원소가 하나일때 
        {
            return arr[start];
        }
        int mid = (start + end) / 2;
        int left = maj(arr, start, mid); // 왼쪽 배열의 과반수 요소
        int right = maj(arr, mid+1, end);
        if (left == right) // 양쪽의 과반수 원소가 같을때
            return left;
        return count(arr, start, mid, left) > count(arr, mid+1, end, right) ? left : right; // 양쪽 배열의 과반수 요소(left, right)가
            // 각 배열에서 몇번 나오는지 세고 많이 나온것이 전체 배열의 과반수 요소
    }
    
    public static int count(int[] arr, int start, int end, int majNum)
    {
        int res = 0;
        for (int i=start; i<end; i++)
        {
            if (arr[i] == majNum)
                res++;
        }
        return res;
    }
    
    
    public static void main(String[] args)
    {
        int[] arr = {2,2,2,4,5,7,3,1,6,2,2,2,2};
        System.out.println(maj(arr, 0, arr.length-1));
    }
}

0개의 댓글