본문 바로가기
코딩 테스트/프로그래머스

[프로그래머스] (Swift) 다음 큰 숫자 - Lv.2

by Dev.Andy 2023. 5. 1.

프로그래머스 문제 이미지: 다음 큰 숫자 - Lv.2

코딩테스트 연습 - 다음 큰 숫자 | 프로그래머스 스쿨

 

📌 풀이

풀이 순서

  1. 우선 주어진 매개변수를 이진수의 문자열로 변환한다.
  2. 결괏값을 n으로 초기화한다.
  3. 십진수를 이진수로 변환하여 1의 개수를 세는 함수를 만든다
  4. 먼저 결괏값을 1 증가시켜 다음 수로 만든다.
  5. 기존의 n 값과 4번의 결괏값으로 3번의 함수를 써서 개수가 같을 때까지 무한 루프를 반복한다.
  6. 5번에서 탈출한 결괏값을 출력한다.

예외 조건

위의 풀이 순서로 하니 테스트 케이스 딱 하나가 시간 초과가 떴다. 아니 무슨... 왜...

혹시나 예제의 데이터처럼 이진수의 숫자가 모두 1인 수는 다음 숫자로 변환하는데 시간이 많이 걸릴까하는 생각이 들었다.

  1. 이진수로 변환했을 때 숫자가 모두 1인 예외 조건
  2. 맨 왼쪽의 1을 기준으로 바로 오른쪽에 0을 삽입한다.
  3. 이를 다시 십진수로 변환하여 반환한다.

까다로웠던 점

예외 조건을 구현하는 데서 애를 먹었다. 내가 아직도 어려워하는 문자열의 메서드와 인덱스 접근이었다.

  1. insert 메서드의 매개변수와 매개변수 이름 - 공식 문서를 봐 가면서 해결을 했다
  2. 아직 익숙하지 않은 String의 index 방식 - binaryN에서 0을 삽입해야 되는데 insert 할 때 인덱스를 넣을 때

 

📌 코드

import Foundation

func solution(_ n:Int) -> Int
{
    // 매개변수를 이진수의 문자열로 변환
    var binaryN = String(n, radix: 2)
    
    // 결괏값을 n으로 초기화
    var result:Int = n

    // 이진수가 1로만 있을 경우
    if binaryN.count == countOneOfBinary(n) {
        // 맨 왼쪽 "1"의 바로 뒤에 "0"을 삽입
        binaryN.insert(Character("0"), at: binaryN.index(binaryN.startIndex, offsetBy: 1))
        
        // 10진수의 정수형으로 변환하여 출력
        return Int(binaryN, radix: 2)!
    }
    
    // 조건을 만족할 떄까지 무한 루프 -> 테스트 하나 시간 초과
    while (true) {
        // 먼저 결괏값을 1 증가
        result += 1
        // 이진수 변환에서 1의 개수가 같으면 반복문 탈출
        if countOneOfBinary(result) == countOneOfBinary(n) {
            break
        }
    }
    
    // 결괏값 반환
    return result
}

// 이진수로 변환하여 1의 개수를 세는 함수 정의
func countOneOfBinary(_ number: Int) -> Int {
    return String(number, radix: 2).filter { $0 == "1" }.count
}

 

📌 번외

1. 처음 보는 메서드

다른 풀이를 보니 nonzeroBitCount라는 메서드로 단번에 해결하는 것을 보고 기가 막혔다. 무슨 이런 메서드가 있담…

nonzeroBitCount | Apple Developer Documentation

2. 공식 문서 하단에 Filter로 단어 검색

기존에는 메서드나 속성을 보기 위해 스크롤을 바쁘게 오르내렸는데, 하단에 Filter 부분이 있는지 몰랐다. 꼭 활용하자!

댓글