프로그래머스/lv2

프로그래머스 : 연습문제 > 연속 부분 수열 합의 개수(lv2

TIN9 2023. 7. 28.
반응형

프로그래머스 링크

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]

코드 풀이

생각해야 할 부분

1. 어떤 자료구조를 사용해야 하냐

문제를 읽어보면 set이 사용될 수 있다는 것을 알 수 있습니다.

연속 부분 수열로부터의 합을 어떠한 자료구조에 넣어야 되는데 이때 중복된 값이 있으면 안 되는 상황이라면

set, map, unordered_map과 같이 중복된 저장이 안되는 자료구조를 사용을 하는데 이중에서도 set은 key값으로만 이루어진 자료구조이기 때문에 set을 사용했습니다.

 

2. 원형인 부분을 어떻게 해결하냐

먼저 원형 수열이다 보니깐 연속 부분 수열의 합을 구할 때 저장되어 있는 꼬리와 머리가 연결이 되어야 한다는 부분을 중점으로 두고 생각을 했습니다.

그래서 간단하게 elements자료구조를 처음부터 끝까지 한 번 더 push_back 해주었습니다.

그러면 부분 수열의 합을 구할 때 편하게 구할 수 있음.

 

3. 2중 포문을 돌릴 때 for(size_t j = i; j < i + Count; ++j)와 같은 코드가 나오는 이유

아마 이 부분이 가장 중요할 거 같은데 말 그대로 문제를 코드로 옮긴 것입니다.

예를 들어 길이가 2인 연속 부분 수열로부터의 합을 구한다고 하면

7+9, 9+1, 1+1, 1+4 + 4+7이 되는 것을 볼 수 있다.

j = i부터 계산을 해야 첫 원소부터 더할 수 있는 것이고 j < i + Count를 해야 길이만큼 더한 값을 얻을 수 있는 것입니다.

 

코드

#include <string>
#include <vector>
#include <set>

using namespace std;

int solution(vector<int> elements) {
    int answer = 0;
    
    set<int> sAddNumb;
    
    size_t elementsSize = elements.size();
    
    for(size_t i = 0; i < elementsSize; ++i)
    {
        elements.push_back(elements[i]);
    }
    
    int Count = 0;
    while(Count < elementsSize)
    {
        for(size_t i = 0; i < elementsSize; ++i)
        {
            int AddNumb = 0;
            for(size_t j = i; j < i + Count; ++j)
            {
                AddNumb += elements[j];
            }
            sAddNumb.insert(AddNumb);
        }
        ++Count;
    }
    answer = sAddNumb.size();
    
    return answer;
}
반응형

댓글