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

2025. 1. 11. 21:35·학습 기록/문제풀이
반응형

문제 설명

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

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

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


풀이

이번에도 시간복잡도에 대한 고려를 하지 않고 그냥 풀어버렸다...

i => 시작 인덱스

j => 마지막 인덱스

로 놓고 i ~ j 까지의 합이 k보다 크면, i를 1 증가시켜 다시 i ~ j까지의 합을 구하는 코드로 작성하였다.

class Solution {
    fun solution(sequence: IntArray, k: Int): IntArray {
        var answer: IntArray = intArrayOf(0, size)
        var sum =0
        for (i in sequence.indices) {
            val term = answer[1] - answer[0]
            val endIndex = minOf(k + i - 1, sequence.size - 1)
            for (j in i..endIndex) {
                if (j - i < term) {
                    sum+= sequence[j]
                    if (sum > k) {
                        break
                    }
                    else if (sum == k) {
                        answer = intArrayOf(i, j)
                        break
                    }
                }
            }
            sum = 0
        }
        return answer
    }
}

어림도 없지 바로 시간초과..

결국 구글링을 통해 투포인터라는 해결방안을 보았고 적용해서 풀었다.

합을 구하는 방법은 비슷해 보이나

첫 풀이는 i ~ j 까지의 합이 k보다 커졌을 때 다시 i를 1 증가시켜 i ~ j 의 합을 다시 처음부터 구하는 방법이라면

투 포인터를 이용한 방식은 기존에 계산한 합을 이용해 구하는 방법이다.

class Solution {
    fun solution(sequence: IntArray, k: Int): IntArray {

        var answer: IntArray = intArrayOf(0, sequence.size-1)
        var startIndex = 0
        var endIndex = 0
        var sum = sequence[endIndex]
        while (startIndex < sequence.size) {
            if (sum < k) {
                if (endIndex == sequence.size - 1) break
                endIndex++
                sum += sequence[endIndex]
            } else {
                if (sum == k) {
                    if(answer[1]-answer[0]>endIndex-startIndex){
                        answer[0] = startIndex
                        answer[1] = endIndex   
                    }
                }
                sum -= sequence[startIndex]
                startIndex++
            }
        }
        return answer
    }
}

 

핵심은 startIndex 와 endIndex인데

  • startIndex부터 endIndex까지의 합이 k보다 작으면
    • endIndex를 1증가시키고 sum에 sequence[endIndex]를 더해준다.
  • startIndex부터 endIndex까지의 합이 k보다 크면
    • sum에서 sequence[startIndex]를 빼주고 startIndex를 1 증가 시킨다.

이렇게 하면 이미 계산된 값을 이용하기 때문에 불필요한 계산이 줄어든다.

 


후기

지난번 것도 그렇고 시간복잡도에 대한 고려를 전혀하지 않고 문제를 푸는 것이 습관이 되어있는 것 같다...

그냥 문제 해결에만 급급한... 

다음 문제부터는 효율적인 방법이 있을지 충분히 고민해 본 후에 문제를 풀어야겠다..!

 

문제 링크

반응형

'학습 기록 > 문제풀이' 카테고리의 다른 글

[프로그래머스] 숫자 카드 나누기 | kotlin  (0) 2025.01.11
[프로그래머스] 롤케이크 자르기 | kotlin  (0) 2025.01.11
[프로그래머스] 덧칠하기 | kotlin  (0) 2025.01.11
[프로그래머스] 달리기 경주 | kotlin  (0) 2025.01.11
[백준 10989] 수 정렬하기 3 | kotlin  (0) 2025.01.07
'학습 기록/문제풀이' 카테고리의 다른 글
  • [프로그래머스] 롤케이크 자르기 | kotlin
  • [프로그래머스] 덧칠하기 | kotlin
  • [프로그래머스] 달리기 경주 | kotlin
  • [백준 10989] 수 정렬하기 3 | kotlin
BaekCCI
BaekCCI
  • BaekCCI
    BaekLog
    BaekCCI
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 학습 기록
        • 안드로이드
        • 문제풀이
        • kotlin
      • 우아한 테크코스
      • 백씨의 하루
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    프로그래머스
    Kotlin
    Algorithm
    알고리즘
    i/o extended android
    Java
    코틀린
    우테코
    백준
    softeer
    androiddeveloper
    소프티어
    우아한테크코스
    gdg korea
    Android
  • 최근 댓글

  • 최근 글

  • 반응형
  • hELLO· Designed By정상우.v4.10.6
BaekCCI
[프로그래머스] 연속된 부분 수열의 합 | kotlin
상단으로

티스토리툴바