처음에는 문제 자체가 이해가 안됐다. 최적의 날짜가 아니라, 되는 날짜를 다 구하는 것이라서 너무 범위가 큰데 이걸 다 ? 이런 느낌이었는데, 완전탐색 느낌으로 한번 해봐야겠다 싶었다.
일단 할인 날짜가 10일이니까, 이걸 최대 10만길이를 어떻게 판단해줄까? 싶어서 이걸 좀 고민하다가 딕셔너리로해서 첫번째 원소를 그다음 원소로 교체해주면서 슬라이딩윈도우 느낌으로 해주면 되지 않을까? 해서 그쪽으로 가닥을 잡고 코드를 짰다.
풀이과정
var answer_dict = [String: Int]()
for i in 0 ..< want.count {
answer_dict[want[i], default: 0] = number[i]
}
var window = discount[0 ..< 10]
var dict = [String: Int]()
for item in window {
dict[item, default: 0] += 1
}
first
를 뽑아주고, 다음날자에 해당하는 친구들 window
에 넣으면서 슬라이딩 윈도우를 업데이트 시켜줄 것이다.
for i in 10 ..< discount.count {
let first = window.removeFirst()
dict[first]! -= 1
window.append(discount[i])
dict[discount[i], default: 0] += 1
if isCorrect() {
answer += 1
}
}
이제 마지막으로 isCorrect()라는 함수를 통해서 현재 윈도우에 내가 사고싶은게 다 담겨있는지만 판단해주면 된다.
딕셔너리를 내가 원하는것, 할인 윈도우의 딕셔너리 를 관리하다보니 변수명땜에 좀 헷갈렸던 것 같다.
func isCorrect() -> Bool {
for fruit in answer_dict {
if let dictValue = dict[fruit.key], dictValue < fruit.value {
return false
}
}
return true
}
import Foundation
func solution(_ want: [String], _ number: [Int], _ discount: [String]) -> Int {
var answer = 0
var window = discount[0 ..< 10]
var answer_dict = [String: Int]()
for i in 0 ..< want.count {
answer_dict[want[i], default: 0] = number[i]
}
var dict = [String: Int]()
for item in window {
dict[item, default: 0] += 1
}
// 반복문에서 카운팅해주기
func isCorrect() -> Bool {
for fruit in answer_dict {
if let dictValue = dict[fruit.key], dictValue < fruit.value {
return false
}
}
return true
}
for i in 10 ..< discount.count {
let first = window.removeFirst()
dict[first]! -= 1
window.append(discount[i])
dict[discount[i], default: 0] += 1
// 여기서 이제 다 들어있는지를 판단 !
if isCorrect() {
answer += 1
}
}
return answer
}
원인을 찾아보니까 예를 들어서 14일까지 있을 때
인덱스 기준으로 0~9, 1~10 , 2~11, 3~12,4~13
이렇게 담겨야하는데, 내가 로직이
for i in 10 ..< discount.count {
let first = window.removeFirst()
dict[first]! -= 1
window.append(discount[i])
dict[discount[i], default: 0] += 1
if isCorrect() {
answer += 1
}
}
이렇게 되어있으니까 처음 담긴 0~9에 대해서는 판단이 안되는 것을 확인했다! 그래서 이걸 수정했다. 그냥 위에다가
if isCorrect() {
answer += 1
}
반복문 시작하기전에 한번 isCorrect()를 돌려줬다 !
결과는..
이번엔 11번은 맞았는데 다른데에서 3~4개 정도 틀렸다.
want : ["apple"] ,
number : [10] ,
discount ["banana","banana","banana","banana","banana",
"banana","banana","banana","banana","banana"]
이렇게 인자를 넣어서 돌려봤는데,
func isCorrect() -> Bool {
for fruit in answer_dict {
if let dictValue = dict[fruit.key], dictValue < fruit.value {
return false
}
}
return true
}
dictValue
에 안들어있으니까 false
뜨는게 아니라, 아예 안거치니까 그냥 통과해서 return true
하고 있더라.. 그래서 이 부분을 더 확실하게 수정해줬다.
func isCorrect() -> Bool {
for fruit in answer_dict {
if let dictValue = dict[fruit.key] {
if dictValue < fruit.value {
return false
}
} else {
return false
}
}
return true
}
fruit.value가 적으면 당연히 false고, 이제 그게 아닌 없는 경우에도 return false
채점 결과
정확성: 100.0
합계: 100.0 / 100.0
import Foundation
func solution(_ want: [String], _ number: [Int], _ discount: [String]) -> Int {
var answer = 0
var window = discount[0 ..< 10]
var answer_dict = [String: Int]()
for i in 0 ..< want.count {
answer_dict[want[i], default: 0] = number[i]
}
var dict = [String: Int]()
for item in window {
dict[item, default: 0] += 1
}
// 반복문에서 카운팅해주기
func isCorrect() -> Bool {
for fruit in answer_dict {
if let dictValue = dict[fruit.key] {
if dictValue < fruit.value {
return false
}
} else {
return false
}
}
return true
}
if isCorrect() {
answer += 1
}
for i in 10 ..< discount.count {
let first = window.removeFirst()
dict[first]! -= 1
window.append(discount[i])
dict[discount[i], default: 0] += 1
if isCorrect() {
answer += 1
}
}
return answer
}
타인의 코드
import Foundation
func solution(_ want:[String], _ number:[Int], _ discount:[String]) -> Int {
var answer = 0
for i in 0..<(discount.count - 9) {
var temp = Array(repeating: 0, count: want.count)
for j in i..<(i + 10) {
if let idx = want.firstIndex(of: discount[j]) {
temp[idx] += 1
}
}
if number == temp {
answer += 1
}
}
return answer
}
이중for문 이긴한데, 내부 반복문은 10번만 돌아가니까 문제는 없고,
want.firstIndex(of: discount[j])
이 부분이 좋게 느껴졌다. want
의 원소를 discount
에서 찾을 생각은 했는데 그 반대를 사용할 지 몰랐다. 그래서 결국 number
배열이랑 똑같게 만들어주면 카운팅해주는거로 깔끔하게 짠 것 같았다.