일단 씻고 나가자

최고의 집합 본문

Coding-Test/프로그래머스를 자바라

최고의 집합

일단 씻고 나가자 2024. 2. 25. 23:56

 

수학적인 직관만 있다면 쉽게 아이디어를 얻고 풀이할 수 있는 문제.

 


 

 

문제 링크 : https://school.programmers.co.kr/learn/courses/30/lessons/12938

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 


 

Problem

정수 n, s 가 주어지며, 's 가 베이스가 되는 특정 조건'에 해당하는 n 개의 0이 아닌 자연수를 찾으면 되는 문제이다.

이때 n 개의 문자는 배열로 return 해야 하며, 오름차순으로 정렬 후 제출해야 한다.

 

'특정 조건' 이란 n 개의 숫자 합이 s 가 되면서, 각 숫자들의 곱이 최댓값이 되게 하는 n 개의 자연수들이다.

예를 들어 n = 3, s = 10 일 때의 예시는 다음과 같다.

 

 

즉, 합이 s 가 될 수 있는 자연수의 집합은 무수히 많지만,

그 중에서 곱이 최댓값이 되는 집합을 반환하라는 문제이다.


 
 

Idea

사실 직관적으로 각 수의 차가 가장 적은 집합이 곱이 최대가 된다는 것을 알 수 있었다.

(이 부분은 산술기하로 인해 증명이 가능하다는데, 추후 수정하여 서술하도록 하겠다)

 

예를 들면

 

다음과 같이 [1, 4] 의 경우에는 두 수의 차가 3이고, [2, 3] 의 경우에는 두 수의 차이가 1인데

이때 개별 수의 곱은 두 수의 차이가 작은 [2, 3] 이 최댓값이 되는 것이다.

 

따라서 정답은 [a, a, a... , a+1...] 형태로 최대 차이가 1이 되는 집합이 되며,

이때 집합의 원소의 개수가 n 개이므로,

 

  • a = s/n (소수점을 버린 정수 값)
  • a+1 은 s%n 개만큼 존재

두 가지 조건을 만족한다면 정답을 산출할 수 있다.

 

직관적으로 n = 3, s = 10 일 때의 정답 산출 플로우는 다음과 같이 진행된다.

 

 

 

 

 

Solution

나의 경우 어차피 정답 배열을 만들어야 하고, 해당 배열을 a 혹은 a+1 로 채워서 return 해야 하기 때문에,

미리 계산한 값으로 for 문을 역순회하며 한 번에 [배열 채우기 + 오름차순] 이 만족하도록 로직을 작성했다.

 

직관적인 플로우는 다음과 같다.

 

 

이때, 문제의 조건에 '원소는 자연수' 라는 조건이 포함됐으므로,

만약 a 가 0인 경우, 즉 s / n (몫) = 0 인 경우는 [-1] 을 반환해주는 검증 로직을 추가해주어야 한다.


 
 

Code

검증 로직 및 for 문의 역순회를 이용하여 풀이한 코드는 다음과 같다.

 

class Solution {
    public int[] solution(int n, int s) {
        
        int quotient = s / n;   // 몫
        int remainder = s % n;  // 나머지
        
        // 몫이 0인 경우 -1 반환
        if(quotient == 0) {
            return new int[] {-1};
        }
        
        
        int[] answer = new int[n];
        
        // for 문을 역순회하며 remainder 만큼 a+1 을 채우고, 그 외에는 a 를 채우는 로직 
        for(int i=answer.length-1; i>=0; i--) {
            answer[i] = remainder-- > 0 ? quotient + 1 : quotient;
        }
        
        return answer;
    }
}

 

 

한 번의 for 문만을 돌았기 때문에 빠른 시간으로 해결할 수 있었던 모습이다.


 

 

End

수학적인 감만 있다면 쉽게 풀 수 있고 그래서 나도 해결할 수 있었지만,

정확한 수학적인 검증과 증명을 알지 못하고 감으로만 풀었기 때문에 조금 아쉬운 문제였다.

다만 여러 케이스를 생각해보고 그들 간의 규칙을 찾는 연습 용으로는 괜찮았다.

조금 더 어려운 문제를 풀어보자.

 

 

 

'Coding-Test > 프로그래머스를 자바라' 카테고리의 다른 글

순위 검색  (0) 2024.07.30
가장 긴 팰린드롬  (0) 2024.06.28
과제 진행하기  (0) 2024.03.21
단체사진 찍기  (0) 2024.02.16
야근 지수  (1) 2024.02.11