3월 13일 TIL (투포인터)

이승원·2024년 3월 13일
0

TIL

목록 보기
41/75
post-thumbnail

프로그래머스 코딩테스트 [ 연속된 부분 수열의 합 ]

Gihub 링크

  • 이 문제는 주어진 숫자 배열에서 제일 적은 연속된 부분 수열의 합이 k가 되는 인덱스를 찾는 문제이다.
  • 시간제한이 없더라면 for 문 두개로 돌면 되곘지만, 배열의 최대 길이가 1,000,000이다. 즉 시간초과를 고려를 꼭 해야한다는 문제라는 것이다.
  • 처음에는 for 문으로 돌려서 break만 잘하면 시간초과가 안되지 않을까 생각을 했는데, 결국 시간초과의 벽에 막히고 말았다.
  • 인터넷을 찾아보니 투포인터 개념이 있었다.
  • 단어 그대로 포인터를 두개를 사용하는것인데, 차이점은 지금까지의 합을 리셋하고 새로 계산하는것이 아니라, 합을 유지한 상태로 사용하는 것이다.
  • 아래 다이어그램 처럼 두개의 포인터를 사용해서 pointer2만 증가 시키면서 지금까지의 합을 유지한다. 만약 pointer2가 움직이면서 sumk보다 커지면 pointer1이 가리키고 있는 elementsum에서 빼버린다. 그리고 pointer11 증가 시킨다. 이렇게 하면 pointer1이 바뀔때마다 pointer2를 새롭게 출발해서 sum을 찾을 필요가 없고, 이미 한번 찾은 sum을 통해 게속 이어 나갈 수 있다.


import Foundation

func solution(_ sequence:[Int], _ k:Int) -> [Int] {
    var indexRecord : [[Int]] = []
    var point1 = 0
    var point2 = 0
    var sum = sequence[0]
    
    while(point1 < sequence.count && point2 < sequence.count){
        if sum == k {
            indexRecord.append([point1,point2])
        }
        
        if sum < k {
            point2 += 1
            if point2 == sequence.count{break}
            sum += sequence[point2]
        }else{
            sum -= sequence[point1]
            point1 += 1
        }
    }
    indexRecord = indexRecord.sorted(by: {
        if $0[1] - $0[0] >= $1[1] - $1[0]{
            return $0[0] < $1[0]
        } else{
            return $0[0] > $1[0]
        }
    })
    
    return indexRecord[0]
}

프로그래머스 코딩테스트 [ 두 큐 합 같게 만들기 ]

Gihub 링크

  • 이 문제도 위 문제와 똑같이 투 포인터를 사용하는 문제다.
  • 주어진 두 큐의 각자의 합이 같게끔 enqueue, dequeue를 사용횟수를 출력하는 문제다.
  • 당연히 처음에는 역시나 큐를 만들어야하나 했지만, 그렇지 않아도 됐었다.
  • 두개의 큐를 하나의 배열로 합치고, 포인터로 추적을 하면 된다는 것이다.
  • 또 하나는 굳이 두개의 큐의 합을 각각 확인할 필요 없이, 하나의 큐가 만약 전체합의 50%가 된다면, 나머지 하나도 무조건 50%이니깐, 하나만 확인하면 된다.

  • 위에 그래프 처럼 작동한다.
import Foundation

func solution(_ sequence:[Int], _ k:Int) -> [Int] {
    var indexRecord : [[Int]] = []
    var point1 = 0
    var point2 = 0
    var sum = sequence[0]
    
    while(point1 < sequence.count && point2 < sequence.count){
        if sum == k {
            indexRecord.append([point1,point2])
        }
        
        if sum < k {
            point2 += 1
            if point2 == sequence.count{break}
            sum += sequence[point2]
        }else{
            sum -= sequence[point1]
            point1 += 1
        }
    }
    indexRecord = indexRecord.sorted(by: {
        if $0[1] - $0[0] >= $1[1] - $1[0]{
            return $0[0] < $1[0]
        } else{
            return $0[0] > $1[0]
        }
    })
    
    return indexRecord[0]
}
profile
개발자 (진)

0개의 댓글