[Algorithme] 연속 부분 수열의 합의 개수

gunggme·2024년 1월 8일

알고리즘

목록 보기
40/42


시작

이 문제는 수가 입력된 배열에서 돌아가면서 배열의 크기만큼 더해서 수열을 구하는 문제이다. 그렇다면, 어느 한 문제와 비슷하다 느낄 수 있다. 그건 물론 옛날 전화기에 있는 그 전화번호 입력 칸과 비슷하다 보면 된다. 우선 한번 알고리즘을 작성해보자

  1. 우선 범위만큼 돌려본다
  2. 2중으로 다시 돌리되 안에는 j + i만큼 돌린다.
  3. 계속 sum에다 더하고, 만약 k가 범위를 벗어나면 k - arrSize에 있는 인덱스를 더한다
  4. 만약 다 돌았을 경우 정렬을 하고, 중복을 제거한, 크기를 return

이런식으로 간단하게 구현을 할 수 있는 문제인 것을 알 수 있다. 그렇다면 한번 코드를 중요한 부분만 한번 봐보자.

for (int j = 0; j < elSize; j++) {
            // 초기화
            int sum = 0;
            for (int k = j; k <  j + i; k++) {
                // 만약 범위를 넘어섰으면
                if (k >= elSize) {
                    sum += elements[k - elSize];
                }
                else {
                    sum += elements[k];
                }
                
            }
            // 배열에 넣기
            indexs.push_back(sum);
        }

이부분이 제일 중요하다. 왜냐 2, 3번에 있는 알고리즘이 제일 중요하기도하고, 이 부분이 없으면 작동하지 않는다. 그렇다면 이 부분은 elSize만큼 돌고, j번부터 j + i만큼 돌게하는 즉, 1번 돌아야되면 0번 index 2칸 확인해야 한다면 0+1, 1+2...,k+k+i씩 도는 코드이다. 그렇게 돌면서 만약 범위를 벗어난다? 그렇다면 바로 elsize만큼 빼버리고 다시 0번 index부터 도는 코드다.

// 정렬을 해야 중복 제거가 원활
    sort(indexs.begin(), indexs.end());
    // 중복제거
    indexs.erase(unique(indexs.begin(), indexs.end()), indexs.end());
    answer = indexs.size();
    return answer;

이부분은 마지막에 답을 내기 위해 사용하는 코드인데. 이 이유는 먼저 "중복"이 들어갔을 경우도 있으니, 먼저 정렬을 해줘야, 중복 제거가 된다. 만약 정렬을 안하고 중복제거를 시도하면 애매하게 남는 것들이 있으니 무조건 정렬을 해줘야한다.

코드

#include<iostream>
#include<string>
#include <vector>
#include <algorithm>

using namespace std;

int solution(vector<int> elements) {
    int answer = 0;
    vector<int> indexs;
    int sum = 0, i = 1, elSize = elements.size();
    while (true) {
        // 만약 범위를 넘어가면 멈추기
        if (i > elSize) break;
        for (int j = 0; j < elSize; j++) {
            // 초기화
            int sum = 0;
            for (int k = j; k <  j + i; k++) {
                // 만약 범위를 넘어섰으면
                if (k >= elSize) {
                    sum += elements[k - elSize];
                }
                else {
                    sum += elements[k];
                }
                
            }
            // 배열에 넣기
            indexs.push_back(sum);
        }
       
        i++;
    }
    // 정렬을 해야 중복 제거가 원활
    sort(indexs.begin(), indexs.end());
    // 중복제거
    indexs.erase(unique(indexs.begin(), indexs.end()), indexs.end());
    answer = indexs.size();
    return answer;
}
profile
안녕하세요!

0개의 댓글