Lv2. 연속된 부분 수열의 합

연속된 부분 수열의 합

프로그래머스 문제

문제 설명

비내림차순으로 정렬된 수열이 주어질 때, 다음 조건을 만족하는 부분 수열을 찾으려고 합니다.

  • 기존 수열에서 임의의 두 인덱스의 원소와 그 사이의 원소를 모두 포함하는 부분 수열이어야 합니다.
  • 부분 수열의 합은 k입니다.
  • 합이 k인 부분 수열이 여러 개인 경우 길이가 짧은 수열을 찾습니다.
  • 길이가 짧은 수열이 여러 개인 경우 앞쪽(시작 인덱스가 작은)에 나오는 수열을 찾습니다.

수열을 나타내는 정수 배열 sequence와 부분 수열의 합을 나타내는 정수 k가 매개변수로 주어질 때, 위 조건을 만족하는 부분 수열의 시작 인덱스와 마지막 인덱스를 배열에 담아 return 하는 solution 함수를 완성해주세요. 이때 수열의 인덱스는 0부터 시작합니다.

시각화

[1, 2, 3, 4, 5] 의 수열이 주어졌을 때 k = 7 일 경우 아래와 같이 부분 수열을 찾을 수 있다.

연속된부분수열의합-1.png

문제 해결 과정

우선 비내림차순이 무엇인지 알아보자.

오름차순과 내림차순은 매우 익숙하나 비내림차순은 처음 들어본 용어였다. 비내림차순은 오름차순과 유사한데 차이점은 중복된 값이 있을 수 있다는 것이다. 데이터베이스에서 오름차순, 내림차순이 익숙하다보니 혼용을 하고 있었던 것 같다. 엄밀히 따지면 오름차순은 중복된 값이 없어야 한다.

문제로 돌아와서 보면 비내림차순으로 정렬된 수열이라는 것은 중복된 값이 있을 수 있는 오름차순이라는 것이다. 이를 요약하면 뒤로 갈수록 값이 커지는 수열이라는 것이다.

이 문제는 two-pointer 를 사용하여 풀 수 있다. 좌우 간격을 두고 합을 계산하면서 k 보다 작으면 우측으로 이동하고 k 보다 크면 좌측으로 이동하면 된다.

left 와 right 을 각각 0으로 두고 시작을 하면서 현재 값이 k 보다 작으면 right 을 증가시키고 k 보다 크면 left 를 증가시킨다. 1, 2, 3 을 다 더해도 7 보다 작기에 right 를 증가시킨다. 연속된부분수열의합-2.png

1, 2, 3, 4 가 되니 10 이 되었기에 left 를 증가시킨다. 연속된부분수열의합-3.png

left 가 증가되면서 3, 4 가 되었다. 바로 return 을 하면 안되는 이유는 뒤에 더 작은 수열의 조합이 있을 수 있기 때문이다.

연속된부분수열의합-4.png

right 를 늘리면서 위와 같은 과정을 반복한다.

연속된부분수열의합-5.png

전체 코드

위 논리를 코드로 적으면 아래와 같다.

def solution(sequence, k):
    answer = []

    l, r = 0, 0
    v = sequence[0]
    while r < len(sequence):
        if r < l:
            break

        if v == k:
            if not answer:
                answer = [l, r]
            else:
                if r - l < answer[1] - answer[0]:
                    answer = [l, r]
            v -= sequence[l]
            l += 1
        if v < k:
            if r >= len(sequence) - 1:
                break

            r += 1
            v += sequence[r]
        if v > k:
            v -= sequence[l]
            l += 1


    return answer


print(solution([1], 1))  # [0, 0]
print(solution([1, 2, 3, 4, 5], 7))  # [2, 3]
print(solution([1, 1, 1, 2, 3, 4, 5], 5))  # [6, 6]
print(solution([2, 2, 2, 2, 2], 6))  # [0, 2]

연속된부분수열의합-6.png


Lv2. 요격 시스템

요격 시스템

Lv3. [PCCP 기출문제] 4번 / 수레 움직이기

수레 움직이기

NCloud LB & SourcePipeline 구축하기
tech collection 서비스 성능 개선하기
Selenium 복권 구매 자동화 만들어보기
디자인 패턴
책 리뷰
블로그 챌린지