HIT해

[Swift/프로그래머스] 퍼즐 게임 챌린지 (이분탐색) 본문

Swift/Swift 알고리즘

[Swift/프로그래머스] 퍼즐 게임 챌린지 (이분탐색)

힛해 2024. 10. 31. 02:21
728x90

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

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

간단한 이분탐색 구현 문제였다.

 

지난 코딩 테스트에서 optional로 출력되는 변수가 골치 아팠는데 이번에도 그러했다.

 

풀이

import Foundation

func solution(_ diffs:[Int], _ times:[Int], _ limit:Int64) -> Int {
    // level의 최솟값을 구하자.
    // level은 0부터 diffs의 최댓값까지로 한뒤 이분탐색을 적용하면 될듯
    var end = diffs.max() ?? 1
    var start = 1
    var result = end
    while start <= end {
        let mid = (end + start)  / 2
        var time = 0
        var time_prev = 0
        for (index,diff) in diffs.enumerated() {
            if diff <= mid {
                time += times[index]
            }else{
                time += (times[index] + time_prev) * (diff - mid) + times[index]
            }
            time_prev = times[index]
        }
        
        if time > limit {
            start = mid + 1
        }else {
            end = mid - 1
            result = mid    
        }
    }
    
    print(result)
    
    return result
}

 

이분탐색 주의점

mid 값을 결과값으로 반환해야할때 어느 부분에서 result 값을 갱신해주느냐가 자꾸 헷갈린다.

 

최솟값 찾기 : end 값을 줄일때 갱신

최댓값 찾기 : start 값을 늘릴때 갱신

 

mid 값 도출할때 start + end / 2 가 아닌 ( start + end ) / 2 인식

두합의 크기가 너무 크다면 start + (end - start ) / 2 를 해도 괜찮다.

 

추가 주의점

optional 출력값 처리방법

  1. ?? 사용
 var end = diffs.max() ?? 1

 

  2. guard let 사용

guard !diffs.isEmpty else { return 0 }

 

1번 방식이 가독성과 작성 시간적으로 보았을때 우수하다.

2번 방식은 왜냐하면 return 타입도 맞춰줘야하기 떄문이다