Skip to content

Instantly share code, notes, and snippets.

@alldroll
Last active December 6, 2019 15:23
Show Gist options
  • Save alldroll/2dc6a85823b96db186e064d6c360617a to your computer and use it in GitHub Desktop.
Save alldroll/2dc6a85823b96db186e064d6c360617a to your computer and use it in GitHub Desktop.
Find the Closest Palindrome
// https://leetcode.com/problems/find-the-closest-palindrome/submissions/
import (
"strconv"
"strings"
)
const (
zero = byte('0')
nine = byte('9')
)
func nearestPalindromic(n string) string {
m := len(n)
num, _ := strconv.Atoi(n)
// case a -> {a-1,a+1}, where a < 9
if m == 1 {
return strconv.Itoa(num - 1)
}
// case aaaaaaa -> 10000001 where a = 9,
nines := strings.Repeat("9", m)
if n == nines {
return strconv.Itoa(num + 2)
}
// case 1000000 -> 999999|1000001
dec, _ := strconv.Atoi("1" + strings.Repeat("0", m-1))
if dec == num {
return strconv.Itoa(num - 1)
}
// case 1000001 -> 999999
if dec+1 == num {
return strconv.Itoa(num - 2)
}
// other cases
c := m / 2
part := n[:c]
v := n[c]
res := make([]string, 0, 3)
if m%2 == 0 {
v = n[c-1]
}
for i := v - 1; i <= v+1; i++ {
candidate := ""
if i >= zero && i <= nine {
if m%2 == 1 {
candidate = part + string(i) + reverse(part)
} else {
bpart := []byte(part)
bpart[c-1] = i
candidate = string(bpart) + reverse(string(bpart))
}
res = append(res, candidate)
}
}
return filter(res, n)
}
func reverse(s string) string {
r := []rune(s)
n := len(r)
for i, j := 0, n-1; i < n/2; i, j = i+1, j-1 {
r[i], r[j] = r[j], r[i]
}
return string(r)
}
func filter(s []string, n string) string {
result := ""
min := (1 << 31) - 1
x, _ := strconv.Atoi(n)
for _, c := range s {
if c == n {
continue
}
y, _ := strconv.Atoi(c)
diff := abs(x - y)
if min > diff {
min = diff
result = c
} else if result > c {
result = c
}
}
return result
}
func abs(x int) int {
if x < 0 {
return -x
}
return x
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment