Leetcode每日一题练习 ------ 564. 寻找最近的回文数

Leetcode 每日一题练习继续讨论:

564. 寻找最近的回文数
564. Find the Closest Palindrome

题解

本题考虑能得到离一个数最近的回文数的所有情况, 假设数字根据长度中间位置有一个"对称轴". 则在对称轴两侧的数字完全按逆序排列即得到回文数, 从原始数字得到回文数可以直接复制左半边的数字并逆序, 可以将左半边数字加一并逆序, 也可以将左半边数字减一并逆序. 只需要比较这几种情况得到的回文数哪个和原数字的差最小即可. 但除此以外还要考虑如999这样的数字, 距离其最近的回文数为1001, 同样对于1000来说, 其对应的回文数为999, 因此需要将这两种情况也考虑在内. 因此对于任意数字, 列举这五种情况下得到的回文数并选择与原数字差最小的即可. 注意对于本身已经是回文数的不能选择自身, 即差必须大于0.

代码

func nearestPalindromic(n string) string {
    num, _ := strconv.Atoi(n)
    
    length := len(n)
    candidates := []int{}
    
    // 情况1:999 -> 1001
    candidates = append(candidates, int(math.Pow10(length)) + 1)
    
    // 情况2:1000 -> 999
    candidates = append(candidates, int(math.Pow10(length-1)) - 1)
    
    // 获取左半部分
    leftHalf := n[:(length+1)/2]
    leftNum, _ := strconv.Atoi(leftHalf)
    
    // 情况3:直接镜像
    candidates = append(candidates, createPalindrome(leftNum, length%2 == 0))
    
    // 情况4:左半部分+1
    candidates = append(candidates, createPalindrome(leftNum+1, length%2 == 0))
    
    // 情况5:左半部分-1
    candidates = append(candidates, createPalindrome(leftNum-1, length%2 == 0))
    
    closest := candidates[0]
    minDiff := abs(num - closest)

    
    for _, candidate := range candidates[1:] {
        diff := abs(num - candidate)
        if (diff < minDiff && diff > 0) || (diff == minDiff && candidate < closest) {
            closest = candidate
            minDiff = diff
        }
    }
    
    return strconv.Itoa(closest)
}

func createPalindrome(num int, even bool) int {
    palindrome := num
    if !even {
        num /= 10
    }
    for num > 0 {
        palindrome = palindrome*10 + num%10
        num /= 10
    }
    return palindrome
}

func abs(x int) int {
    if x < 0 {
        return -x
    }
    return x
}

1 个赞

帮顶 算法我真是完全看不懂

1 个赞

刷题佬!我又来了

1 个赞

绑定,我真看不懂

1 个赞

From 算法 to 开发调优