1️⃣ 문제
2️⃣ 풀이 방법 및 코드
해당 문제는 그리디 유형이지만, 최근에 올라온 반례의 테스트 케이스로 완전 탐색 풀이로 풀었다.
-
알파벳을 바꾸는 up, down은 따로 각 인덱스 마다 아스키 코드 차이 값을 이용해서 up과 down 두 방향으로 알파벳 조정 시 min값을 구하고 더해주었다.
-
연속되는 A 구간이 많다면, A 이전까지 갔다가 다시 돌아와서 뒤로 가서 수정하는 방법이 커서 횟수가 적을 수가 있다.
-
기본값은 오른쪽으로 한칸씩 이동하는 name.count - 1
-
특정 인덱스 다음부터 A가 있다면, 끝나는 A 지점 찾아주기
-
문자열 각 특정 인덱스를 기준으로 오른쪽으로 해당 인덱스까지 갔다가 다시 돌아와서 A 끝나는 구간으로 뒤로 가는 방법과,
A 끝나는 구간으로 먼저 뒤로 갔다가 다시 원점 돌아와서 해당 인덱스까지 가는 방법의 커서 횟수를 구하고
-
미리 구한 좌우 이동 커서 횟수와 이들을 비교해 작은 값으로 새로 저장해준다.
-
-
업다운과 좌우 더해준 값을 리턴하면 끄읕@!
소스 코드
import Foundation
func solution(_ name:String) -> Int {
var name = Array(name)
// 1. 알파벳 조정
let upDown = name.map {
let upCnt = Int($0.asciiValue! - 65)
let downCnt = Int(90 - $0.asciiValue! + 1)
return min(upCnt, downCnt)
}.reduce(0, +)
// 2. 커서 이동 횟수
var leftRight = name.count - 1 // 2-1
name.enumerated().forEach {
// 2-2
var endA = $0.0 + 1
while endA < name.count && name[endA] == "A" {
endA += 1
}
// 2-3
let leftFirstCnt = $0.0 * 2 + (name.count - endA)
let rightFirstCnt = (name.count - endA) * 2 + $0.0
let move = min(leftFirstCnt, rightFirstCnt)
// 2-4
leftRight = leftRight < move ? leftRight: move
}
// 3
return upDown + leftRight
}