[프로그래머스] 체육복 (swift)

728x90

문제

코딩테스트 연습 - 체육복

문제 분석

여분이 있는 학생은 앞, 뒤 학생에게만 빌려줄 수 있고, 여분이 있어도 도난 당했을 수 있다는 전제를 처리를 하고,

빌려주는 로직을 짜면 될 거 같다.

알고리즘

  1. Set의 차집합을 활용하여 lost와 reserve 배열을 비교하여 여유분을 도둑맞은 처리를 해 준다.
  2. reserve의 값을 가지고 lost를 순회하면서 빌려줄 수 있는지 확인, 가능하다면 삭제처리(대여)를 한다
  3. 총 인원 수와 lost의 배열 개수를 빼서 리턴한다.

코드

import Foundation

func solution(_ n:Int, _ lost:[Int], _ reserve:[Int]) -> Int {
    //여벌을 가져왔지만 도난당할 수 있으니 그거에 대한 전처리 먼저한다.
    var losts = Set(lost).subtracting(reserve).sorted()
    let reserves = Set(reserve).subtracting(lost).sorted()
		//sorted()로 다시 뽑아준건, Set은 무질서 컬렉션이라 순회작업에 적합하지 않다.

    //여벌 옷이 있는 친구는 앞 뒤 사람만 빌려줄 수 있다.
    for item in reserves {
        for index in 0..<losts.count {
            if losts[index] == item-1 {
                losts.remove(at: index)
                break;
            }
            else if losts[index] == item+1{
                losts.remove(at: index)
                break;
            }
        }
    }
    
    return n-losts.count
}

문제 해결 중 어려웠던 것

집합을 생각해내서 제외 시키는 데 문제는 없었지만, 계속 17,18,19 테스트 케이스가 틀렸다고 나왔었다.

알고보니 Set은 unordered collection으로 순서가 보장되지 않은 collection이여서 오류가 나온거 같다...

sorted()를 사용해서 다시 배열로 반환시켜주니 문제없이 원래 로직대로 해결 할 수 있었다!

다른방식

import Foundation

func solution(_ n:Int, _ lost:[Int], _ reserve:[Int]) -> Int {
    // 체육복애 여별의 수를 저장하는 배열, 초기값은 0
    var clothCount = Array(repeating: 0, count: n)
    
    // 체육복을 읽어 버린 경우 -1로 설정
    for i in lost { clothCount[i-1] = -1 }
    
    // 여벌 체육복이 있는 경우 1로 설정
    for j in reserve { clothCount[j-1] = 1 }
    
    // 전체 학생의 여벌 체육복 배열을 인덱스와 값을 하나씩 비교하면 순회
    for (index, k) in clothCount.enumerated() {
        // 현재 학생이 체육복을 읽어 버린 경우
        if k == -1 {
            // 앞의 학생이 여벌 체육복이 있는지(== 1) 비교한 후 있으면 빌림
            if index > 0 && clothCount[index-1] == 1 {
                clothCount[index] += 1
                clothCount[index-1] += -1
            }
            // 뒤의 학생이 여벌 체육복이 있는지 비교한 후 있으면 빌림
            else if index < clothCount.count - 1 && 
                    clothCount[index+1] == 1 {
                clothCount[index] += 1
                clothCount[index+1] += -1
            }
        }
    }
    
    // 최소 체육복이 있는 경우(>= 0)의 학생의 수를 최종 반한
    return clothCount.filter{ $0 >= 0 }.count
}
  • 전체 학생의 체육복 개수를 관리하는 변수 만들기관리하는 변수를 만들고, 잃어버린 경우, 여벌이 있는 경우에 값을 변경해주면서 해결하는 방식이였다.
  • 이렇게 해결 했어도 금방 끝날 문제였던거 같다.
728x90