728x90
카카오 블라인드 문제를 못풀면... 기분이 안좋다... ㅠㅠ
[1차]인거 보면... 어렵지 않은 문제라고 생각하고 출제되었을텐데... 나는 왜 못풀었는가...?
중간정도는 답을 찾는 과정에 근접했다고 생각하지만 결국 끝을 맺지 못했다! 그래서 여러 블로그를 참고하였는데 내가 생각했던 방식의 접근과 가장 유사했던 분이 계셔서 그 분의 블로그를 참고했다.
이 문제를 풀면서 생각한 논리적 흐름
- 먼저 짚고 넘어가야할 옵션들부터 해결하였다. lowercased를 사용하여 대소문자를 통일하였고
- 그렇게 통일 시켰을 때 만약 배열의 값이 똑같다면 65536을 바로 리턴해주면 됐다.
- 또한 알파벳이 아닌 특수문자, 공백, 기호 등이 들어갈 경우 한 번 더 걸러서 알파벳 원소들의 조합만 남길 수 있도록했다.
- 그 다음 과정에서 원소들이 배열들이 몇개나 중복되는지 Dictionary를 이용해서 걸러주었다.
- 이 다음 과정으로 arrFirst와 arrSecond간의 intersection(교집합), sumofset(합집합)을 구하고 그 구해진 원소들의 개수를 dictionary로 파악하고자 했다.
- 그 후 나온 원소들의 개수로 자카드 유사도 방식의 값을 내고자 했다.
- 하지만 5~6 과정이 너무 복잡하여 오랜 고민을 하다가 다른 블로거 분들의 코드를 봤다.
- 참고한 블로거분의 코드는 lowercased부터 알파벳 확인까지 모두 딕셔너리를 만드는 함수 안에 넣어 굉장히 깔끔하게 진행하셨고
- intersectionCount 이 부분이 적어놓은 코드만 보면 오 그렇네 맞네 이런 생각이 절로 드는데... 내가 막상 하려고하면 뇌가 정말 가렵다...
- 결론은 이 분도 딕셔너리의 키 값을 이용해 공통된 키 값의 value중 min과 max를 사용하여 값을 구하셨다.
* 내가 적은 틀린 코드
func solution(_ str1:String, _ str2:String) -> Int {
let first = Array(str1.lowercased().map{String($0)})
let second = Array(str2.lowercased().map{String($0)})
var arrFirst: [String] = []
var arrSecond: [String] = []
var dictFirst: [String: Int] = [:]
var dictSecond: [String: Int] = [:]
var intersection: Set<String> = []
var sumSet: Set<String> = []
if first == second {
return 65536
}
for i in 0...first.count-2 {
let temp = String(first[i]) + String(first[i+1])
if isAlphabet(temp) {
arrFirst.append(temp)
}
}
for i in 0...second.count-2 {
let temp = String(second[i]) + String(second[i+1])
if isAlphabet(temp) {
arrSecond.append(temp)
}
}
for i in arrFirst {
if dictFirst[i] != nil {
dictFirst[i]! += 1
} else {
dictFirst[i] = 1
}
}
for i in arrSecond {
if dictSecond[i] != nil {
dictSecond[i]! += 1
} else {
dictSecond[i] = 1
}
}
return 0
}
func isAlphabet(_ str: String) -> Bool {
for char in str {
if !char.isLetter { return false }
}
return true
}
* 참고한 답안 코드
import Foundation
func makeDict(_ str: String) -> [String: Int] {
let str = Array(str)
let len = str.count
var result = [String: Int]()
for i in 0..<len-1 where str[i].isLetter && str[i+1].isLetter {
let key = String([str[i], str[i+1]]).lowercased()
if result[key] == nil { result[key] = 0 }
result[key]! += 1
}
return result
}
func solution(_ str1:String, _ str2:String) -> Int {
let mux: Double = 65536
let s1 = makeDict(str1)
let s2 = makeDict(str2)
let s1Key = Set(s1.keys.map { String($0) })
let s2Key = Set(s2.keys.map { String($0) })
let commonKey = s1Key.intersection(s2Key)
let sumKey = s1Key.union(s2Key)
let intersectionCount = commonKey.reduce(0) { partialResult, key in
partialResult + min(s1[key]!, s2[key]!)
}
let unionCount = sumKey.reduce(0) { partialResult, key in
partialResult + max(s1[key] ?? 0, s2[key] ?? 0)
}
if unionCount == 0 { return Int(mux) }
return Int(Double(intersectionCount)/Double(unionCount) * mux)
}
정리(Today I Learned)
- 알고리즘 문제 풀기는 너무 어렵지만 항상 한끝 차이다. 수학 문제랑 똑같다... 많이 풀고 틀린거 다시 보고 정말 기초적인 원리를 알고.
이 세가지를 앞으로 3개월만 반복해보자!
'TIL > 알고리즘 공부' 카테고리의 다른 글
프로그래머스 Lv. 2 Swift 알고리즘 - 귤 고르기 (0) | 2023.01.09 |
---|---|
프로그래머스 Lv. 2 Swift 알고리즘 - 타겟 넘버 (0) | 2023.01.09 |
프로그래머스 Lv. 2 Swift 알고리즘 - 프린터 (0) | 2023.01.09 |
프로그래머스 Lv. 2 Swift 알고리즘 - n^2 배열 자르기 (0) | 2023.01.08 |
프로그래머스 Lv. 2 Swift 알고리즘 - 기능개발 (0) | 2023.01.08 |