[회고] 신입 iOS 개발자가 되기까지 feat. 카카오 자세히보기

🍎 Apple/Swift

[Swift] 순열과 조합 구현

inu 2022. 4. 25. 15:36
반응형

지난 포스팅에서 Queue를 구현해봤는데요

알고리즘 문제에는 순열 및 조합도 가끔 쓰이죠!

 

그래서 이번엔 순열과 조합을 구현해봤습니다.


순열 (Permutation)

순열은 전체에서 중복없이 순서를 고려해 n개를 배열하는 경우의 수입니다.

해당 특성에 맞게 DFS를 사용해 접근했습니다.

 

따라서 Stack과 재귀함수 둘 모두를 사용할 수 있습니다.

Stack 사용

func permutation<T: Comparable>(_ array: [T], _ n: Int) -> [[T]] {
    var result = [[T]]()
    if array.count < n { return result }

    var stack: [([T], [Bool])] = array.enumerated().map {
        var visited = Array(repeating: false, count: array.count)
        visited[$0.offset] = true
        return ([$0.element], visited)
    }

    while stack.count > 0 {
        let now = stack.removeLast()

        let elements = now.0
        var visited = now.1

        if elements.count == n {
            result.append(elements)
            continue
        }

        for i in 0...array.count-1 {
            if visited[i] { continue }
            visited[i] = true
            stack.append((elements + [array[i]], visited))
            visited[i] = false
        }
    }

    return result
}

재귀함수 활용

func permutation<T: Comparable>(_ array: [T], _ n: Int) -> [[T]] {
    var result = [[T]]()
    if array.count < n { return result }

    var visited = Array(repeating: false, count: array.count)

    func cycle(_ now: [T]) {
        if now.count == n {
            result.append(now)
            return
        }

        for i in 0..<array.count {
            if visited[i] {
                continue
            } else {
                visited[i] = true
                cycle(now + [array[i]])
                visited[i] = false
            }
        }
    }

    cycle([])

    return result
}

조합 (Combination)

조합은 전체에서 중복없이 순서를 고려하지않고 n개를 배열하는 경우의 수입니다.

해당 특성에 맞게 DFS를 사용해 접근했습니다.

 

따라서 이 역시 Stack과 재귀함수 둘 모두를 사용할 수 있습니다.

Stack 사용

func combination<T: Comparable>(_ array: [T], _ n: Int) -> [[T]] {
    var result = [[T]]()
    if array.count < n { return result }

    var stack = array.enumerated().map { ([$0.element], $0.offset) }

    while stack.count > 0 {
        let now = stack.removeLast()

        let elements = now.0
        let index = now.1

        if elements.count == n {
            result.append(elements.sorted())
            continue
        }

        guard index+1 <= array.count-1 else { continue }

        for i in index+1...array.count-1 {
            stack.append((elements + [array[i]], i))
        }
    }

    return result
}

재귀함수 활용

func combination<T: Comparable>(_ array: [T], _ n: Int) -> [[T]] {
    var result = [[T]]()
    if array.count < n { return result }

    func cycle(_ index: Int, _ now: [T]) {
        if now.count == n {
            result.append(now)
            return
        }

        for i in index..<array.count {
            cycle(i + 1, now + [array[i]])
        }
    }

    cycle(0,[])

    return result
}
반응형

'🍎 Apple > Swift' 카테고리의 다른 글

[Swift] JSON Encoding / Decoding  (0) 2022.05.12
[Swift] ATS (App Transport Security)  (0) 2022.05.12
[Swift] Queue (Deque) 구현  (0) 2022.04.25
[Swift] Method Swizzling  (0) 2022.04.10
[Swift] Localizing (NSLocalizedString)  (5) 2022.04.10