코딩테스트/프로그래머스

프로그래머스 연속 부분 수열 합의 개수

의현 2025. 4. 7. 17:42

링크 : https://school.programmers.co.kr/learn/courses/30/lessons/131701


문제 풀이

Ver1.

첫 번째 반복문 : size 1부터 최대 elements 크기만큼 진행

두 번째 반복문 : i(특정 위치) + size 만큼 합을 구하고 answer에 추가

  • i(특정위치) + size가 elements 크기보다 작다면 [i ~ i+size]의 합을 구하여 answer에 추가하면 됨
  • elements 크기보다 크다면 [i ~ elements 크기] 만큼 구하고(tmp) 남은 갯수를 [0 ~ remain_count]만큼 추가로 더해주면 됨
    • 원형 수열이기 때문에 남은 값은 0 ~ remain_count만큼 구해서 추가로 더해주면 됨
  • 최종적으로 answer.size를 리턴하면 해결
function solution(elements) {
    var answer = new Set([]);
    
    for (let size = 1; size <= elements.length; size++) {
        for (let i = 0; i < elements.length; i++) {
            if (i + size <= elements.length) {
                answer.add(elements.slice(i, i + size).reduce((acc, cur) => {
                    return acc += cur
                }, 0));
            } else {
                let tmp = elements.slice(i, elements.length).reduce((acc, cur) => {
                    return acc += cur
                }, 0);
                let remain_count = size - (elements.length - i);
                tmp += elements.slice(0, remain_count).reduce((acc, cur) => {
                    return acc += cur
                }, 0);
                answer.add(tmp);
            }
        }
    }
    
    return answer.size;
}

Ver2.

원형 수열의 원리를 조금이용하면 elements를 2개 붙여 원형 수열처럼 보이게 할 수 있음 -> 위 코드에서 remain_count를 계산할 필요가 없어짐

function solution(elements) {
    // 배열을 하나 더 붙여서 0부터 elements.length-1 인덱스까지 순회하면서 길이만큼 splice
    const array = [...elements, ...elements];

    const count = new Set();
    for (let i = 1; i <= elements.length; i++) {
        for (let j = 0; j < elements.length; j++) {
            const part = array.slice(j, j+i);

            count.add(part.reduce((acc, cur) => acc+cur));
        }
    }
    return count.size;
}

결론

배열의 합을 구하기 위해 reduce 메서드 사용 (자세한 정보는 mdn 참고)

특정 배열의 구간을 나눈 것은 slice 메서드를 사용해 해당 범위의 새로운 배열을 얻음