clamp
Clamp
clamp
글쓰기 관리
전체 방문자
오늘
어제
  • 분류 전체보기 (509)
    • IOS (85)
    • SwiftUI+TCA+Combine (9)
    • RxSwift + MVVM (56)
    • Clean Architecture (12)
    • SWIFT (56)
    • iOS - TDD (2)
    • 디자인패턴 (4)
    • CS (56)
      • 알고리즘 (29)
      • 운영체제 (15)
      • 자료구조 (2)
      • 네트워킹 (4)
      • 기타 (6)
    • 회고 (0)
    • Firebase (18)
    • SwiftUI (10)
    • iOS - UIKit (11)
    • iOS - 오픈소스 (6)
    • 코딩테스트 (166)
      • 프로그래머스 (164)
    • 정보처리기사 (14)
    • GitHub (2)
글쓰기 / 관리자

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • ㅅ
  • Q
  • uikit
  • Swift

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
clamp

Clamp

코딩테스트/프로그래머스

코딩테스트 - [Swift] 귤고르기

2023. 1. 5. 20:52

귤 고르기

문제 설명

 

경화는 과수원에서 귤을 수확했습니다. 경화는 수확한 귤 중 'k'개를 골라 상자 하나에 담아 판매하려고 합니다. 그런데 수확한 귤의 크기가 일정하지 않아 보기에 좋지 않다고 생각한 경화는 귤을 크기별로 분류했을 때 서로 다른 종류의 수를 최소화하고 싶습니다.

예를 들어, 경화가 수확한 귤 8개의 크기가 [1, 3, 2, 5, 4, 5, 2, 3] 이라고 합시다. 경화가 귤 6개를 판매하고 싶다면, 크기가 1, 4인 귤을 제외한 여섯 개의 귤을 상자에 담으면, 귤의 크기의 종류가 2, 3, 5로 총 3가지가 되며 이때가 서로 다른 종류가 최소일 때입니다.

경화가 한 상자에 담으려는 귤의 개수 k와 귤의 크기를 담은 배열 tangerine이 매개변수로 주어집니다. 경화가 귤 k개를 고를 때 크기가 서로 다른 종류의 수의 최솟값을 return 하도록 solution 함수를 작성해주세요.


제한사항
  • 1 ≤ k ≤ tangerine의 길이 ≤ 100,000
  • 1 ≤ tangerine의 원소 ≤ 10,000,000

 

입출력 예
k       tangerine                                 result
6 [1, 3, 2, 5, 4, 5, 2, 3] 3
4 [1, 3, 2, 5, 4, 5, 2, 3] 2
2 [1, 1, 1, 1, 2, 2, 2, 3] 1

입출력 예 설명

입출력 예 #1

  • 본문에서 설명한 예시입니다.

입출력 예 #2

  • 경화는 크기가 2인 귤 2개와 3인 귤 2개 또는 2인 귤 2개와 5인 귤 2개 또는 3인 귤 2개와 5인 귤 2개로 귤을 판매할 수 있습니다. 이때의 크기 종류는 2가지로 이 값이 최소가 됩니다.

입출력 예 #3

  • 경화는 크기가 1인 귤 2개를 판매하거나 2인 귤 2개를 판매할 수 있습니다. 이때의 크기 종류는 1가지로, 이 값이 최소가 됩니다.

접근 방법

귤의 수를 정확히 맞출 필요는 없다.

귤의 크기의 범위는 정해져있다.

  • 1 ≤ tangerine의 원소 ≤ 10,000,000

이므로 귤의 크기 만큼 배열을 생성해주는데 배열의 최대 크기 는 귤의 크기의 최대치로 설정한다.

(귤 크기별 개수를 알기 위해서이다)

 

1. 귤의 크기별로 몇 개가 포함되어 있는지 배열에 추가해준다

      귤의 크기가 50이라면 numlist[50] 을 +1, 귤의 크기가 132라면 numlist[132]를 해준다.

2. 겹치는 귤의 개수가 많은 순서대로 내림차순 정렬을 해준다.

3. 필요한건 겹치는 귤의 크기 종류의  수.

    겹치는 귤의 크기 종류의 수를 구할 때 가장 많은 개수의 귤부터 차례대로 귤의 개수에 더해주면 된다.

    귤의 개수에 더하지만 필요한건 크기별 종류의 수 이므로 한 개의 종류를 더해줄 때 마다 answer에 + 1을 해준다.

4. 선택 조건( 조건 설명)

 

필요 귤 개수.   현재까지 추가한 귤의 수         선택된 귤크기 종류        남은 배열(크기별 귤의 개수)

       6                            0                                             0                    [4, 3, 2, 1, 0]

 

 

해당 조건에서 시작했다고 가정할 경우 첫 번째로 4를 선택했을 때 아래처럼 된다.

 

 

  필요 귤 개수.   현재까지 추가한 귤의 수         선택된 귤크기 종류        남은 배열(크기별 귤의 개수)

       6                            4                                             1                     [3, 2, 1, 0]

 

 라고 쳤을 경우 다음 귤의 수는 꼭 2일 필요가 없다

그냥 첫 번째인

3을 선택하면 된다.

귤 개수를 정확하게 맞출 필요가 없다.

우린 3개의 귤을 선택하지만 실제로 포장할 땐 크기가 3인 귤을 2개만 넣으면 되기 때문이다.

 

달리 말해 귤의 개수가 부족한건 안되지만 귤의 개수가 넘치는건 허용된다는 뜻.

 

변수 설명

max : 귤의 최대 크기 (불 필요한 공간 낭비를 덜기 위해)

numlist : 귤의 크기 별 귤의 개수를 저장할 배열

answer: 귤 크기 종류의 수

count: 선택된 귤의 수

 

실패코드

시간초과

for i in numlist{

}

내에서 계속 removeFirst()가 실행되며 배열 내애서의 삭제, 재배치가 모든 반복마다 이루어지면서 시간초과가 발생했다.

func solution(_ k:Int, _ tangerine:[Int]) -> Int {
    let max = tangerine.max()!
    var numlist = Array(repeating: 0, count: max + 1)
    for i in tangerine{
        numlist[i] += 1
    }
    
//    var count = numlist.reduce(0){ $0 + $1}
    numlist.sort(by: >)
    // 종류의 수
    var answer = 0
    //귤의 수
    var count = 0
    for i in numlist{
        if( count < k ){
            count += numlist.first!
            numlist.removeFirst()
            answer += 1
        }
    }
    return answer
}

성공코드

func solution(_ k:Int, _ tangerine:[Int]) -> Int {
// 공간 낭비를 줄이기 위해 귤의 최대크기를 배열의 최대크기로
    let max = tangerine.max()!
    //귤 크기별 개수를 저장할 배열
    var numlist = Array(repeating: 0, count: max + 1)
    //귤 크기별 개수를 센다
    for i in tangerine{
        numlist[i] += 1
    }
    
    //귤 크기별 개수의 내림차순으로 정렬한다
    numlist.sort(by: >)
    // 귤 크기 종류의 수
    var answer = 0
    //선택 된 크기의 귤의 수
    var count = 0
    
    //배열 요소는 몇개까지 있나.
    let howmany = numlist.count
    
    //0번 인덱스(가장 큰 수)부터 차례대로 접근
    for i in 0..<howmany{
        //선택된 귤의 수가 목표치보다 적다면
        if( count < k ){
            //가장 많은 귤부터 추가한다.
            count += numlist[i]
            //한 종류의 크기를 선택했으니 1증가
            answer += 1
        }
    }
    return answer
}

지속적인 배열의 Update가 아니라 요소를 순회하며 귤의 수를 추가하는거로 업데이트.

저작자표시 비영리 동일조건 (새창열림)
    '코딩테스트/프로그래머스' 카테고리의 다른 글
    • 코딩테스트 - [Swift] 단어변환(BFS)
    • 코딩테스트 - 타겟 넘버(DFS)
    • 코딩테스트 - [Swift] 모의고사(완전탐색)
    • 코딩테스트 - [Swift] 최소직사각형(완전탐색)
    clamp
    clamp
    주니어 iOS개발자의 발악!!!!!!!

    티스토리툴바