오늘도 알고리즘 풀이로 TIL을 작성한다.
빠르게 가보자
반복문에 중독되버린 것인지 이것도 반복문으로 풀었다
func solution(_ n:Int) -> String {
var result = ""
for i in 1...n {
if i % 2 == 0 {
result += "박"
} else {
result += "수"
}
}
return result
}
단순하게 i가 홀수일 때 "수"를 짝수일 때 "박"을 추가하도록 했다.
문자열끼리는 +
연산이 가능해서 쉽게 추가했다
무난하게 통과했지만 요즘 너무 반복문만 사용하는것 같아서
메소드를 이용해서 다시 풀이해봤다
func solution(_ n: Int) -> String {
return (1...n).map { $0 % 2 == 0 ? "박" : "수" }.joined()
}
음 확실히 간결해졌다. 이대로 제출하니 통과했다
후에 익숙해지긴 하겠지만 아직 어색한 방법인것같다
아 저번에 실행 시간 차이가 나던게 신기해서 이번에도 결과를 봤는데
이게 첫번째 풀이 방법의 소요시간이고
다음이 두번째 풀이 방법이다
저번처럼 소요시간 자체는 메소드를 사용하는 쪽이 더 많이 소모된다.
코드가 깔끔하게 작성되는 것도 좋지만 실제 데이터 인풋이 많은 상황에서는 단순 반복문이 성능상으론 좋을 수도 있겠다고 생각했다.
실제 프로젝트에 들어갔을때 어떤걸 써야할지 고민이 많이 될거같다.
다음 문제인데 또 반복문이다
이제 반복문없이 살 수 없을지도
func solution(_ a:[Int], _ b:[Int]) -> Int {
var result = 0
for i in 0..<a.count {
result += a[i] * b[i]
}
return result
}
이것 역시 다른 방법을 찾아 보려고 다른 분들의 풀이를 참고해봤다
func solution(_ a:[Int], _ b:[Int]) -> Int {
return zip(a, b).map(*).reduce(0, +)
}
처음본 건 zip
이라는 메소드인데 배열을 결합시켜주는 연산자인것 같다.
예를 들어 a = [1, 2, 3]
, b = [4, 5, 6]
이라는 배열이 있다면 이것을 (1,4), (2,5), 3,6)
같은 방식으로 결합해준다.
그후 map(*)
을 통해 곱연산자를 추가하고 ex)(1 * 4)
reduce
메서드로 모든 요소를 결합하여 반환한다.
음.. 이 문제는 처음에 보고 좀 고민을 했다
처음에 left부터 right까지의 수를 반복문으로 돌리고
약수를 찾은후 조건문을 통해 풀려고 했으나
약수도 반복문을 통해서 해야하기 때문에 이중 for문이 될거같아서 고민했다
고민해봐도 이 방법밖에 생각이 안나서 일단 풀었다
func solution(_ left:Int, _ right:Int) -> Int {
var result = 0
for i in left...right {
let count = factor(i)
result += (count % 2 == 0) ? i : -i
}
return result
}
func factor(_ num: Int) -> Int{
var count = 0
for i in 1...num {
if num % i == 0 {
count += 1
}
}
return count
}
약수 구하는 부분을 factor
함수로 빼서 그나마 가독성을 높이려고 했다
무튼 해결은 했지만 뭔가 찜찜해서 다른 사람들 풀이를 봤다
눈에 띄는 풀이는 아래의 것이다
func solution(_ left: Int, _ right: Int) -> Int {
return (left...right).map { i in (1...i).filter { i % $0 == 0 }.count % 2 == 0 ? i : -i }.reduce(0, +)
}
고차함수를 사용해서 한줄로 길게 작성하셨다.
메서드에 대한 이해도는 높아 보이지만 개인적으로는 가독성이 좀 떨어진다고 생각했다
그 외 다른 사람들의 풀이는 내것과 유사하나 조금씩 변경점이 있는 정도다.
이 문제는 처음에 보고 어 쉬운데?하고 접근했다
처음에는 아래처럼 풀었다
func solution(_ s:String) -> String {
return Array(s).sorted(by:>).joined(separator: " ")
}
근데 오류가 나서 아래와 같이 수정했다.
func solution(_ s: String) -> String {
return String(s.sorted(by: >))
}
근데 이 풀이는 통과했다가도 런타임 에러가 뜨거나 특정 테스트에서 계속 시간이 초과되는 경우가 있어서 다시 수정했다
func solution(_ s: String) -> String {
let sortedCharacters = s.sorted(by: >)
return String(sortedCharacters)
}
이렇게 하니 특이사항 없이 통과했다
전의 풀이와 비교하면 문자열의 정렬을 변수에 할당을 했느냐 안했느냐의 차이인데 왜 에러가 떴는지는 모르겠다
다른 사람의 풀이중에서 참고할만한 것은
func solution(_ s:String) -> String {
return String(s.sorted { $0 > $1 })
}
이 풀이였다
단순 내림비교가 아닌 두개의 요소를 비교하여 정렬하는 방식
어찌보면 이 방식이 더 효율적일수 있겠다
쉬운문제 같았는데 제법 애먹은 문제였다
갑자기 방대해진 설명에 쉽지 않아보이는 문제라고 생각했다.
그래도 차분히 뜯어보니 풀이 방법이 보였다
이렇게 포인트를 잡고 풀었다
func solution(_ price:Int, _ money:Int, _ count:Int) -> Int64{
var answer:Int = -1
var sum: Int = 0
for i in 1...count {
sum += price * i
}
answer = money - sum
return answer < 0 ? Int64(abs(answer)) : 0
}
마지막 return
부분에서 괜히 헷갈렸는데
돈이 모자랄때만 0보다 값이 작고 나머지 상황(돈이 딱 맞거나, 충분하거나) 하는 상황은 0이상의 값이 나온다
이 부분은 급하게 푸느라 헷갈린것같다
다른 사람들 풀이를 보니 정말 간단하게 푼 사람들이 있더라
func solution(_ price:Int, _ money:Int, _ count:Int) -> Int{
return max((count + 1) * count / 2 * price - money , 0)
}
이렇게 간단하게 푸는 사람들 보면 존경스러울 정도
또 하나의 풀이가 있었는데
func solution(_ price:Int, _ money:Int, _ count:Int) -> Int64{
let totalPrice = price * (count * (count+1)/2)
if money >= totalPrice {
return 0
}
return Int64(totalPrice - money)
}
둘의 겉모양은 다르지만 (count * (count+1)/2)
이 부분이 공통인데 찾아보니 등차수열을 이용한 방식이더라
이렇게 수학적인 사고가 들어간 풀이는 처음보는거 같아서 신기했다. 한 수 배워가는 느낌
문자열 공부하자고 어제 생각했는데 바로 관련 문제가 나왔다
비교적 간단하게 풀이했다
func solution(_ s:String) -> Bool {
if s.count == 4 || s.count == 6 {
return Int(s) != nil ? true : false
} else {
return false
}
}
난 이것도 제법 간단하게? 풀었다고 생각했는데
뛰는 놈위에 나는 놈 있다더니 더 심플한 풀이가 있다
func solution(_ s:String) -> Bool {
return (Int(s) != nil && (s.count == 4 || s.count == 6)) ? true : false
}
내가 한 풀이를 축약한 느낌의 코드다.
이 풀이가 가장 와닿았는데
요즘 시도해보려는 메서드를 사용하는 간략한 풀이 방법인데 조건을 설정하는 부분에서 생각이 꼬여서 안했던 방법이다.
다음 문제 풀이부터는 좀 더 차분하게 생각을 정리할 수 있도록 해야겠다
알고리즘 마스터.. 모르는 문제 여쭤보겠습니다 :)