23.03.18 - 프로그래머스 코딩테스트 입문 - 최댓값 만들기 (2)

0

TIL

목록 보기
74/126

문제 :
정수 배열 numbers가 매개변수로 주어집니다. numbers의 원소 중 두 개를 곱해 만들 수 있는 최댓값을 return하도록 solution 함수를 완성해주세요.


가장 먼저, 내가 처음 생각했던 방법은 단순히 배열을 돌려서 가장 큰 수와, 그 다음으로 큰 수를 곱하기로 생각해보았다.
하지만 입출력 예를 보다가 이해했던 것이 위에서 생각했던 방식을 사용하게된다면 (-) * (-)이것과 같이 음수 끼리 곱하게되면 양수가 되므로, 답이 틀리게 나온다는 것이었다.

그렇다면 번거롭더라도 일단은 for문으로 모든 경우의 수를 곱해 결과값이 가장 큰 수를 찾는 것이다.
자바의 코드로 내가 생각한 이 방법 외에 더 간단한 방법이 있겠지만, 일단은 내가 가능한 방법으로 우선 코딩을 해보려한다.

public int solution(int[] numbers) {
    int maxNum = 0;
    for (int i = 0; i < numbers.length; i++) {
        for (int j = i + 1; j < numbers.length; j++) {
            if (maxNum < numbers[i] * numbers[j]) {
                maxNum = numbers[i] * numbers[j];
            }
        }
    }
    return maxNum;
}

시간 복잡도 : O(N^2)
공간 복잡도 : O(1)
테스트는 통과했다. 하핳 이 코드는 실패작이었다.
하지만 for문 안에 for문 안에 if문이라니...
이것은 예비개발자로서 절대로 용납할 수 없는 수준의 코드라고 생각하므로 다른 방법을 생각해본다.


위에 작성해본 난잡한 코드가 아닌 뭔가 굉장히 자바스럽고 먹음직스러운 방법이 있지 않을까 열심히 고민해봤지만 나의 머리만으로는 좋은 방법이 떠오르지 않았고
구글링을 해보니 비슷한 문제 풀이 방법으로 배열을 정렬하여 가장 큰 수 두개와 가장 작은 수 두개를 곱하고 비교해서 큰 수를 반환하는 방법을 알게되었다.
이 방법만으로도 훨씬 더 깔끔해보이지만 Math.max라는 자바 함수도 알게되었다. 이는 두 수를 비교하여 값이 큰 수를 반환해주는 함수이다.

public int solution(int[] numbers) {
    int leng = numbers.length;
    Arrays.sort(numbers);
    int lowNum = numbers[0] * numbers[1];
    int hightNum = numbers[leng - 1] * numbers[leng - 2];
    return Math.max(lowNum, hightNum);
}

시간 복잡도 : O(N log N)
공간 복잡도 : O(1)
정말 깔끔하고 함수의 용도만 알게된다면 코드 해석도 정말 간단하게 가능한거같다.


나의 습관은 내가 가장 처음 단순한 방법을 생각하고나면 거기에 꽂혀서 다른 방법은 생각하기가 어렵다는 것이다.
Array.sort는 코딩테스트를 해보면서 많이 보았었고, Math.max는 코딩테스트에서 은근히 많이 쓰일거같다.
이렇게 나는 오늘도 성장해따!

++++++++++++++++++++++++++++++++++++++++++++

혹시나 궁금해서 내가 작성했던 위에 코드로 프로그래머스 코드를 제출해봤는데
총 12개의 테스트 중 7번째 테스트에서 실패가 발생했다!
경우의 수를 고민을 해보니 모든 결과 값이 0보다 작은 음수일 경우,
처음 작성한 구린 코드에서는 처음에 maxNum을 0으로 초기화했기 때문에 모든 값이 0보다 작아서 결과값이 무조건 0이 반환돼서 오류가 발생했다.

0개의 댓글