Algorithms/프로그래머스

[프로그래머스] '연속된 수의 합' - Java

LEFT 2022. 12. 16. 11:29

<문제 제시>

연속된 세 개의 정수를 더해 12가 되는 경우는 3, 4, 5입니다. 두 정수 num과 total이 주어집니다. 연속된 수 num개를 더한 값이 total이 될 때, 정수 배열을 오름차순으로 담아 return하도록 solution함수를 완성해보세요.

<예시 입출력>


<문제 해결 과정>

연속된 수를 더하면 되지만, '연속된 수의 개수'와 '연속된 수의 총합'만 주어지기때문에 조금 어렵게 느껴졌다.

총합과 개수만 보고 임의의 수가 어떻게 이뤄질지 유추하는 문제이다.

Try 1) java.lang.ArrayIndexOutOfBoundsException: 3 오류 발생

public static int[] solution(int num, int total) {
        int[] answer = new int[num];
        
        // total과 비교하기 위한 합계 변수
        int sum = 0; 
        
        // break문이 입력될때까지 무한 반복
        while(true){
            int sign = 0;
            int val = num; // 값의 개수
            
            // Case 1. total이 sum보다 크거나 sum이 0일때
            if(sum == 0 || total > sum){
                for(int i = 0; i < num; i++){
                    // 값의 개수만큼 (3이면 0,1,2 = 3번) 반복
                    sum += val; // 3이면 3을 더하고 1증가시킴 >> 3이면 3,4,5가 더해져 12가됨
                    val++;
                }
                sign = 0; // Case 1을 표시
            }
            
            // Case 2. total이 sum보다 작을때
            if(total < sum){
                for(int i = 0; i < num; i++){
                    sum += val;
                    val--;
                }
                sign = 1; // Case 2를 표시
            }
            
            // Case 3.total가 비교군 sum이 일치하면 반복문 종료
            if(total == sum) {
            	break; 
            } else { // 그렇지 않은 경우
                if(sign == 0) num--; // Case 1일 경우 num을 감소시킴
                else num++; // Case 2일 경우 num을 증가시킴
            }
        
        }
        
        System.out.println(num);
        System.out.println(answer.length);
        // 위에서부터 구해진 num을 answer에 차례대로 넣음 (증가시키며)
        for(int i = 0; i < num; i++){
            answer[i] = num;
            num++;
        }
        
        return answer;
	}

여러 Case를 나눠서 하나하나 조건을 처리할 수 있도록 하였지만 Index 범위 오류가 발생하였다. 

answer에 더하는 과정에서 문제가 발생한 것 같았다.

Solution 1) 수정결과

만약 num = 3이고 total = 12이면 연속된 수의 중간값을 구한 후 중간 값에서 -1, +1을 해주어 순차적으로 설정해주면

될 것 같았다.

int n = total / num;
int middle = num / 2;
int idx = 0;

먼저 '연속된 수의 개수' = num 가

1) 짝수일 경우

// 주어진 개수가 짝수일 경우
if(num % 2 == 0) {
    // 인덱스 값은 개수에서 중간을 뺀값의 +1
    idx = n - middle + 1;
}

2) 홀수일 경우

else idx = n - middle;

num 이 3일경우는 홀수이므로 (12 / 3) - (3 / 2) = 4 - 1 = 3

idx는 3이 된다.

이처럼 짝수, 홀수로 구분하여 임의 인덱스 값을 지정한다. 

for반복문에서는 이 인덱스(idx)값을 초기값으로하여 (total / num) 한 값과 >> ex) 12 / 3 = 4

(num / 2) 인 middle값 >> ex) 3 / 2 = 1 을 

더한 값까지 반복한다. (ex. 5까지)

int k = 0;
for(int i = idx; i <= n + middle; i++) { 
    answer[k] = i;
    k++;
}

answer를 관리할 인덱스가 더 필요하므로 int k = 0를 임의적으로 지정하였다.

그렇다면, 3을 초기값으로하여 5까지 반복한다.

answer[0] = 3
answer[1] = 4
answer[2] = 5


<전체코드>

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

// #. 연속된 수의 합
public class continuous_sum {
	
	/* 
	<문제설명>
	1. 연속된 임의의 수 num개를 더한 값이 total이 될때
	2. 정수배열을 오름차순으로 return
	*/
	
	public static int[] solution(int num, int total) {
        int[] answer = new int[num];
        
        int n = total / num;
        int middle = num / 2;
        int idx = 0;
        
        // 주어진 개수가 짝수일 경우
        if(num % 2 == 0) {
        	// 인덱스 값은 개수에서 중간을 뺀값의 +1
        	idx = n - middle + 1;
        }
        else idx = n - middle;
        
        int k = 0;
        for(int i = idx; i <= n + middle; i++) { 
        	answer[k] = i;
        	k++;
        }
        
        return answer;
	}
	
	public static void main(String[] args) throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		
		// 첫번째 변수 입력
		System.out.print("입력 = ");
		int data1 = Integer.parseInt(br.readLine());
		
		// 두번째 변수 입력
		System.out.print("입력 = ");
		int data2 = Integer.parseInt(br.readLine());
		

		System.out.println(Arrays.toString(solution(data1, data2)));
	}

}

프로그래머스의 자체 입력방식보다 BufferedReader를 이용하여 입력을 받고 solution을 호출해보았다.


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

 

프로그래머스

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

programmers.co.kr