코딩 테스트(Coding Test)/프로그래머스

[프로그래머스] 연속 부분 수열 합의 개수 - 자바(Java)

잇트루 2023. 8. 29. 00:46
반응형

문제 링크

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

 

프로그래머스

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

programmers.co.kr

 

 

문제 설명

철호는 수열을 가지고 놀기 좋아합니다. 어느 날 철호는 어떤 자연수로 이루어진 원형 수열의 연속하는 부분 수열의 합으로 만들 수 있는 수가 모두 몇 가지인지 알아보고 싶어 졌습니다. 원형 수열이란 일반적인 수열에서 처음과 끝이 연결된 형태의 수열을 말합니다. 예를 들어 수열 [7, 9, 1, 1, 4]로 원형 수열을 만들면 다음과 같습니다.

원형 수열은 처음과 끝이 연결되어 끊기는 부분이 없기 때문에 연속하는 부분 수열도 일반적인 수열보다 많아집니다.

 

원형 수열의 모든 원소 elements가 순서대로 주어질 때, 원형 수열의 연속 부분 수열 합으로 만들 수 있는 수의 개수를 return 하도록 solution 함수를 완성해 주세요.

 

 

제한사항

  • 3 ≤ elements의 길이 ≤ 1,000
  • 1 ≤ elements의 원소 ≤ 1,000

 

 

입출력 예

elements result
[7, 9, 1, 1, 4] 18

 

 

입출력 예 설명

입출력 예 #1

길이가 1인 연속 부분 수열로부터 [1, 4, 7, 9] 네 가지의 합이 나올 수 있습니다.

길이가 2인 연속 부분 수열로부터 [2, 5, 10, 11, 16] 다섯 가지의 합이 나올 수 있습니다.

길이가 3인 연속 부분 수열로부터 [6, 11, 12, 17, 20] 다섯 가지의 합이 나올 수 있습니다.

길이가 4인 연속 부분 수열로부터 [13, 15, 18, 21] 네 가지의 합이 나올 수 있습니다.

길이가 5인 연속 부분 수열로부터 [22] 한 가지의 합이 나올 수 있습니다.

이들 중 중복되는 값을 제외하면 다음과 같은 18가지의 수들을 얻습니다.

[1, 2, 4, 5, 6, 7, 9, 10, 11, 12, 13, 15, 16, 17, 18, 20, 21, 22]

 

 

코드

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

class Solution {
    public int solution(int[] elements) {
        // elements의 2배 크기의 배열 생성
        int[] newElements = new int[elements.length * 2];

        // newElements의 i와 i + elements.length 위치에 elements[i] 저장
        for(int i = 0; i < elements.length; i++) {
            newElements[i] = elements[i];
            newElements[i + elements.length] = elements[i];
        }

        // 중복을 제거하기 위한 Set 생성
        Set<Integer> set = new HashSet<>();

        // 부분 수열의 합 구하기
        for(int i = 0; i < elements.length; i++) {
            for(int j = 0; j < elements.length; j++) {
                // 새 배열에서 j부터 j+i-1까지의 부분 배열의 합을 구하고 Set에 추가
                set.add(Arrays.stream(newElements, j, j+i).sum());
            }
        }

        // 개수 반환
        return set.size();
    }
}

코드 설명

주석 참고

  • 이 문제는 배열 elements를 원형 수열로 취급하여 연속하는 부분 수열의 합의 개수를 구하는 문제다.
  • elements 배열의 두 배 크기인 newElements 배열을 선언하고, elements 배열의 값을 순회하면서 elements[i]를 newElements[i], newElements[i + elements.length]에 저장하여 원형 배열처럼 구성한다.
  • 부분 수열의 합을 중복 제거하면서 저장하기 위해 Set을 선언한다.
  • 이중 반복문과 스트림을 활용하여 부분 수열의 합을 구한다.
  • 첫 번째 반복문에서는 부분 수열을 구하기 위한 크기 i를 지정한다. (1부터 elements의 길이까지)
  • 두 번째 반복문에서 elements 배열의 j번째 요소부터 크기인 i까지 합하여 set에 저장한다. (크기가 i인 부분 수열의 합)
반응형