Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions WEEK03/프로그래머스_뉴스클러스터링/Liv.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// 프로그래머스 - 뉴스 클러스터링

func solution(_ str1: String, _ str2: String) -> Int {
var arr1: [String] = toSplit(str1.lowercased())
var arr2: [String] = toSplit(str2.lowercased())

var intersection: Int = 0

if arr1.isEmpty, arr2.isEmpty { return 65536 }

for item in arr1 {
if let idx = arr2.firstIndex(of: item) {
intersection += 1
arr2.remove(at: idx)
}
}

let union = arr1.count + arr2.count
Comment on lines +11 to +18

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

교집합을 계산하기 위해 arr1을 순회하면서 arr2에서 firstIndex(of:)remove(at:)를 호출하는 방식은 O(N*M)의 시간 복잡도를 가집니다. 이는 배열의 크기가 클 때 비효율적입니다. 한쪽 배열을 빈도수 맵(Dictionary)으로 만들어두면 교집합을 O(N+M) 시간 복잡도로 찾을 수 있어 성능이 크게 향상됩니다. 또한, 합집합 계산 로직도 더 명확하게 표현할 수 있습니다.

    var map2 = arr2.reduce(into: [String: Int]()) { $0[$1, default: 0] += 1 }
    
    for item in arr1 {
        if let count = map2[item], count > 0 {
            intersection += 1
            map2[item]? -= 1
        }
    }
    
    let union = arr1.count + arr2.count - intersection

return intersection * 65536 / union
}

func toSplit(_ str: String) -> [String] {
var string = str
var result: [String] = []
while !string.isEmpty {
var item: String = String(string.prefix(2))
item.removeAll { !$0.isLetter }
if !item.isEmpty, item.count == 2 {
result.append(item)
}
string.removeFirst()
}
return result
Comment on lines +23 to +33

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

while 루프 내에서 string.removeFirst()를 사용하는 현재 구현은 O(N^2)의 시간 복잡도를 가집니다. Swift에서 String의 맨 앞 문자를 제거하는 것은 문자열 길이에 비례하는 비용이 드는 연산이기 때문입니다. 이로 인해 긴 문자열이 입력될 경우 성능이 크게 저하될 수 있습니다. 문자열을 배열로 변환하고 인덱스를 통해 순회하는 방식으로 O(N) 시간 복잡도로 개선할 수 있습니다.

    var result: [String] = []
    let characters = Array(str)
    
    if characters.count < 2 {
        return result
    }
    
    for i in 0..<(characters.count - 1) {
        let first = characters[i]
        let second = characters[i+1]
        
        if first.isLetter && second.isLetter {
            result.append("\(first)\(second)")
        }
    }
    
    return result

}