Highest Value Palindrome
September 02, 2018 - [palindrome]
흔한 팰린드롬(좌우대칭 문자열) 관련 문제이지만 이틀 동안 너무 고생했던 문제ㅠ https://www.hackerrank.com/challenges/richie-rich/problem
문제
0~9 까지 숫자로 이루어진 문자열과 자연수 k가 입력으로 주어진다. 주어진 문자열을 팰린드롬으로 변환하기 위하여 변경작업이 k번까지 허용된다고 할 때 만들 수 있는 팰린드롬 문자열 중 가장 큰 값의 팰린드롬 문자열을 리턴하는 함수를 작성하라.(단, k번 만에 팰린드롬 문자열을 만들 수 없을 경우에는 -1을 리턴한다)
입력 예)
6 3
092282
출력 예
992299
js코드
function highestValuePalindrome(s, n, k) {
function getMincnt(s) {
var cnt = 0
for (var i = 0; i < s.length / 2; i++) {
if (s[i] !== s[s.length - 1 - i]) {
cnt++
}
}
return cnt
}
var m = getMincnt(s) // palindrome 만들기 위한 필요 변경 개수
if (k < m) {
return -1
}
var rest = k - m // 여윳돈(m번의 변경작업을 제외하고 남는 추가 변경작업 기회)
var sarr = s.split("")
for (var i = 0; i < n / 2 && k > 0; i++) {
if (i === n - 1 - i) {
// 정가운데까지 도착했으면
sarr[i] = "9"
break
}
if (sarr[i] === sarr[n - 1 - i]) {
if (sarr[i] === "9") {
// 양끝이 모두 9인 경우
continue
} else {
// 양끝이 모두 9가 아닌 경우
if (rest >= 2) {
// 양끝 값이 이미 같기 때문에 굳이 변경을 하지 않아도 되지만 여윳돈이 있다면 최대값을 만들기 위해 9로 치환하도록 한다
sarr[i] = "9"
sarr[n - 1 - i] = "9"
k -= 2 // 변경작업 2회 사용
rest -= 2 // 추가작업 찬스 2회 사용(여윳돈 사용))
} else {
continue
}
}
} else {
if (sarr[i] === "9" || sarr[n - 1 - i] === "9") {
// 양끝 중 하나가 9라면 무조건 9로 세팅
sarr[i] = "9"
sarr[n - 1 - i] = "9"
k-- // 변경작업 1회 사용
} else {
if (rest >= 1) {
// 여윳돈이 있으면 양끝 두개모두 9로 세팅
sarr[i] = "9"
sarr[n - 1 - i] = "9"
k -= 2 // 변경작업 2회 사용
rest-- // 추가작업 찬스 1회 사용(어짜피 1회는 사용했어야 하는 경우이므로)
} else {
// 여윳돈이 없다면 그냥 짝만 맞추고 다음으로
var max = Math.max(sarr[i], sarr[n - 1 - i])
sarr[i] = max
sarr[n - 1 - i] = max
k-- // 변경작업 1회 사용
}
}
}
}
return sarr.join("")
}
풀이 리뷰
짧은 입력값이 주어질 경우 사람이 풀기에는 어렵지 않은 문제지만 그 풀이방법을 로직으로 꼼꼼히 작성하기가 상당히 까다로웠다. 그냥 처음부터 찬찬히 풀이과정을 꼼꼼히 분기조건으로 나타내면서 풀어냈으면 이리 오래 걸리진 않았을 터인데 대충 때려 맞추려다가 오히려 훨씬 더 많은 시간을 소비하고 말았다.