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

kiki·2024년 1월 11일
0

프로그래머스

목록 보기
56/79

문제 링크

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

문제 설명

  • 원형 수열의 모든 원소 elements가 순서대로 주어질 때, 원형 수열의 연속 부분 수열 합으로 만들 수 있는 수의 개수를 return

1차 시도 - 통과 but

def solution(elements):
    tmp = []
    l = len(elements)
    for i in range(0, l):
        for j in range(l):
            if j+i+1>l:
                tmp.append(sum(elements[j:]+elements[:(j+i+1)%l]))
            else:
                tmp.append(sum(elements[j:j+i+1]))
    return len(set(tmp))

단순 무식하게 element의 길이만큼 반복하며 시작 순서를 달리해 연속 부분 수열을 구해 합을 리스트에 담아두고 마지막에 중복을 제거해 길이(연속 부분 수열 합으로 만들 수 있는 수의 개수)를 반환했다.

근데 이렇게 하나하나 맞춰가며 코드를 작성하다보니 코드가 복잡해지고 코드를 작성한 나조차도 헷갈렸다.
좋은 코드가 아니니, 다른 코드를 살펴봐야겠다 생각

다른 사람의 풀이

def solution(elements):
    ll = len(elements)
    res = set()

    for i in range(ll):
        ssum = elements[i]
        res.add(ssum)
        for j in range(i+1, i+ll):
            ssum += elements[j%ll]
            res.add(ssum)
    return len(res)

생각의 전환!! 나같은 경우엔 길이가 1인 연속 부분 수열을 시작 위치를 변경해가며 구하고, 그 다음 길이가 2인 연속 부분 수열,,, 이렇게 구했었는데,

  • 이 사람들은 시작 위치를 고정해두고 길이가 1,2,3,4,..인 연속 부분수열을 구함.
  • ssum이라는 하나의 변수를 두고 이에 다음 값을 더하고, set에 추가함으로써 연속 부분 수열의 합을 구함...
  • 인덱스를 j%ll로 원형수열의 인덱싱을 간단하게..!
  • 처음부터 set을 사용함으로써 중복을 제거

이러니 코드가 가독성이 좋고, 간단해졌다.
정말 배울 게 많은 코드다.

즉 연속 부분 수열의 길이는 1~len(elements)이니 첫번째 for문에서 시작의 위치를 바꿔주면서 i에서부터 1~len(elements) 의 합을 set에 넣어준다...이야

정리

  • 순서를 뒤바꿔 생각해보자
  • for문에서 하나의 변수를 이용해 연속 부분 수열의 합을 구할 수 있다.
  • i%len 연산을 통해 원형 수열의 인덱싱이 가능
  • 중복을 원치 않는다면 처음부터 set을 사용. set.add()를 사용해 원소 추가가 가능하다.

0개의 댓글