blues_log

오늘 학습한 내용

  • Java 문법 복습
  • 프로그래머스 문풀 ( 코딩테스트 입문 Lv.0 끝 !!)

문제상황

오늘의 삽질은 이 문제에서 하게 되었다.

https://school.programmers.co.kr/learn/courses/30/lessons/120923

 

프로그래머스

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

programmers.co.kr


시도한 내용

우선 이 문제를 해결하기 위해 다양한 방법을 생각해보려고 노력을 했는데 가장 원초적인 방법밖에 떠오르지 않았다.

떠오른 방법은 다음과 같다.

  • -total < a < total 을 만족하는 정수 a를 담을 수 있는 배열을 만든다.
  • 예를 들어, total이 3이면 [-3, -2, -1, 0, 1, 2, 3] 의 배열을 만드는 것이다.
  • 이제 for문을 활용하여 주어진 num의 길이를 가지는 배열에 순서대로 인덱스 값을 넣고 비교한다.
  • 처음에 [-3, -2, -1]을 담고 더한다음 total과 비교한다.
  • 만약 일치하면 배열을 return하고 틀리면 다음 경우를 생각한다.
  • 한 칸 옮겨서 [-2, -1, 0] 과 total을 비교한다. .... 이 과정 반복

정말 효율적인 방법이 아니라고 생각했지만 당장 생각나는 방법이 이 경우밖에 없어서 이 것을 토대로 코드를 작성했다.

 

어찌저찌 정답률이 90%까지는 통과가 되는 로직이 구현이 되었다.

하지만 위 논리에서는 total이 0인 경우를 제대로 처리하지 못한다.

 

예를 들어, total이 0, num이 3이면 배열로 [-1, 0, 1]을 리턴해야하는데 위의 논리로는 [0]을 리턴한다.

그래서 위 논리에서 total이 0인 경우를 나누고 거기에 num이 짝수인 경우, 홀수인 경우도 나눠서 코드를 구현하면 엄청나게 복잡해지고 정말 효율적이지 않은 코드라고 생각해서 이 코드는 모두 지우고 새로 생각하게 되었다.

 

여러가지 방법을 끄적여보다가 문득 등차수열이 생각났다.

연속된 수의 특징은 공차가 1인 등차수열과 같고, 더해야 하는 개수(num)과 결과(total)이 주어져 있으므로 등차수열의 첫째항을 구하면 나머지는 for문을 사용하여 배열을 채우면 되는 거였다.

 

우선 등차수열의 합 공식은 다음과 같다.

 

여기서 S == total, n == num, d == 1 이다.

여기서 식 변형을 하면 a = total/num - (n-1)/2가 된다.

 


해결

위의 내용을 토대로로직을 작성했다.

class Solution {
    public int[] solution(int num, int total) {
        int[] answer = new int[num];
        
        // 첫번째 항 구하기 (등차수열의 합 공식 이용)
        int a1 = total/num - (num-1)/2;
        // System.out.println(a1);
        
        for(int i=0; i<num; i++) {
            answer[i] = a1+i;
        }
        
        return answer;
    }
}

결과는 통과

 

로직도 굉장히 간단하고 처음 생각했던 내용에 비해 불필요한 과정들이 굉장히 많이 줄어들었다고 생각했다.


알게된 내용

알고리즘을 풀 때 수학을 정말 잘 알고 있으면 다양한 공식들을 활용할 수 있다는 것을 느끼게 되었다.

정말 어려운 대학수학 내용은 활용하기 어렵겠지만 쉬운 수학 공식들은 까먹지 않도록 자주 봐야겠다는 생각을 하게 되었다.

 

그리고 오늘 프로그래머스 코딩 테스트 입문 문제를 모두 해결했다. 캠프가 끝나기 전까지는 Lv2까지 있는 모든 문제를 해결하고 싶고, 더 어려운 문제도 도전하고 싶다.