본문 바로가기

iOS 앱 개발자 프로젝트/알고리즘 코드카타

[Algorithm] 가장 많이 받은 선물 (w/ Swift)

 

오늘은 가장 최신 문제(2024 KAKAO WINTER INTERNSHIP )를 풀어보자! ᵔᴗᵔ

 

가장 많이 받은 선물
 

프로그래머스

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

programmers.co.kr

 

"누가 선물을 많이 받았나?"

  • 각 친구가 주고받은 선물에 대한 기록을 바탕으로 누가 가장 많이 선물을 받았는지 찾는 문제야.
  • 선물을 주고받은 기록이 주어지고, 그 기록을 보고 가장 많은 선물을 받은 친구가 몇 명인지 구해야 해.

 

나의 코드

func solution(_ friends: [String], _ gifts: [String]) -> Int {
    var answer = 0
    let dic = friends.enumerated().reduce(into: [String: Int]()) { $0[$1.element] = $1.offset }
    var intArray = [Int](repeating: 0, count: friends.count)
    var giftArrays = [[Int]](repeating: [Int](repeating: 0, count: friends.count), count: friends.count)

    for gift in gifts {
        let stringArray = gift.components(separatedBy: " ")
        guard let giverIndex = dic[stringArray[0]], let receiverIndex = dic[stringArray[1]] 
        else { break }

        giftArrays[giverIndex][receiverIndex] += 1
        intArray[giverIndex] -= 1
        intArray[receiverIndex] += 1
    }
    for i in intArray.indices {
        var count = 0

        for j in 0..<intArray.count {
            guard i != j else {
                continue
            }
            if giftArrays[j][i] < giftArrays[i][j] || (giftArrays[j][i] == giftArrays[i][j] && intArray[i] < intArray[j]) {
                count += 1
            }
        }
        if answer < count {
            answer = count
        }
    }
    return answer
}

 

 

코드 설명

  1. 딕셔너리와 배열 준비
    • 먼저 dic은 친구의 이름을 인덱스에 매핑하는 딕셔너리야. 이걸로 친구 이름을 기준으로 인덱스를 찾을 수 있어. 예를 들어, ["A", "B", "C"]가 있다면, dic["A"]는 0, dic["B"]는 1, dic["C"]는 2 이런 식이야.
    • giftArrays: 2D 배열을 만들어서, 각 친구가 다른 친구에게 준 선물 개수를 기록할 거야.
    • intArray: 각 친구가 받은 선물의 차이를 기록하는 배열. 예를 들어, intArray[i]는 친구 i가 받은 선물의 개수를 나타내.
  2. 선물 기록 업데이트
    • 주어진 선물 기록(gifts)을 하나씩 확인하면서 선물 주고받은 내용을 기록해.
    • giftArrays[giverIndex][receiverIndex]는 giverIndex가 receiverIndex에게 준 선물 수를 증가시켜.
    • intArray[giverIndex]는 선물을 보냈으니까 -1, intArray[receiverIndex]는 선물을 받았으니까 +1을 해.
    이 부분이 핵심이야! 선물을 주고받을 때마다 선물의 흐름을 잘 기록하는 거야.
  3. 가장 많이 선물을 받은 친구 찾기
    • 이제 각 친구가 받은 선물의 개수를 비교해서, 누가 가장 많이 선물을 받았는지 계산해.
    • 친구 i와 다른 친구 j를 비교하면서, giftArrays[j][i] < giftArrays[i][j]이면 i가 더 많이 받은 거니까 카운트를 증가시켜.
    • 만약 giftArrays[j][i] == giftArrays[i][j]일 경우에는 intArray[i]와 intArray[j]를 비교해. 선물 받은 총합을 비교하는 거야.
      예를 들어, 친구 i는 선물을 더 많이 보내고 친구 j는 더 많이 받았으면, i가 더 많은 선물을 받았다고 판단하는 거지.
  4. 결과
    • 각 친구에 대해 이 비교를 다 끝내면, 가장 많이 선물을 받은 친구의 수를 answer에 저장해서 반환!

 


 

 

예시로 천천히 이해해 보자

let friends = ["A", "B", "C"]
let gifts = ["A B", "B A", "C A", "A C"]

 

  • friends: ["A", "B", "C"]
  • gifts: ["A B", "B A", "C A", "A C"]

 

  1. 선물 주고받은 기록을 giftArrays와 intArray에 반영:
    • "A B" → A는 B에게 선물을 주고, B는 A에게 선물을 받음.
    • "B A" → B는 A에게 선물을 주고, A는 B에게 선물을 받음.
    • "C A" → C는 A에게 선물을 주고, A는 C에게 선물을 받음.
    • "A C" → A는 C에게 선물을 주고, C는 A에게 선물을 받음.
  2. giftArrays (선물 주고받은 기록):
    • A가 B에게 선물을 준 횟수: giftArrays[0][1]
    • A가 C에게 선물을 준 횟수: giftArrays[0][2]
    • B가 A에게 선물을 준 횟수: giftArrays[1][0]
    • C가 A에게 선물을 준 횟수: giftArrays[2][0]
  3. intArray (받은 선물의 차이):
    • A는 선물을 2개 받았고, 2개를 보냈으니까 0으로 유지.
    • B는 선물을 1개 받았고, 1개를 보냈으니까 0으로 유지.
    • C는 선물을 1개 받았고, 1개를 보냈으니까 0으로 유지.
  4. 누가 가장 많이 선물을 받았는지 확인:
    • giftArrays와 intArray를 비교해서 가장 많이 선물을 받은 친구는 **"A"**야.
  5. 최종 결과는 answer에 가장 많은 선물을 받은 친구의 수, 즉 2명이 된다는 거야..٩(  ˙༥˙  )و