leetcode 564 寻找最近的回文数

Find the Closest Palindrome
Given an integer n, find the closest integer (not including itself), which is a palindrome.

The ‘closest’ is defined as absolute difference minimized between two integers.

Example 1:
Input: “123”
Output: “121”
Note:
The input n is a positive integer represented by string, whose length will not exceed 18.
If there is a tie, return the smaller one as answer.

解题思路

分情况模拟:
注意1000,1000001等情况
和与原来一样的情况
最后比较三种状态

  1. 按从中间开始后面的与前面的相等的状态
  2. 中间或最靠近中间的半部分的第一个数数加1后按照前半部分给后面赋值的状态
  3. 同样上面那个数减一,同样方法的回文数
    这三个数与原数据进行差值运算,找到最接近的即可

代码

class Solution {
public:
    void is(string &n) {
        auto id = n.size()/2;
        for (; id < n.size(); ++id)
            n[id] = n[n.size()-id-1];
        return;
    }
    string nearestPalindromic(string n) {
        if (n.size() == 1) {
            n[0] = (n[0] == '0'?'1':n[0]-1);
            return n;
        }
        string k(n.size()-1, '9'), kss(n.size(), '9') ;
        if (kss == n) {
            string kss(n.size()+1, '0');
            kss[0] = kss[kss.size()-1] = '1';
            return kss;
        }
        if (n[0] == '1') {
            int is = 0;
            for (auto i : n)
                if (i >= '1') is++;
            if (is == 2 && *(n.end()-1) == '1') is --;
            if (is == 1) {
                return k;
            }
        }
        k = n;
        is(n);
        string s1 = n, s2 = n;
        sub(s1, -1);
        sub(s2, 1);
//        cout << n << " " << s1 << " " << s2 << endl;
        long long kk = stoll(k), ss1 = kk-stoll(s1), ss2 = stoll(s2)-kk, tm = abs(kk-stoll(n));
        ss2 = min(ss1, ss2);
        if (ss2 == ss1)
            kss = s1;
        else
            kss = s2;
        if (n == k)
            return kss;
//        cout << ss2 << " " << tm << endl;
        if (ss2 > tm)
            return n;
        else if (ss2 == tm)
            return min(kss, n);
        else return kss;
    }
    void sub(string &t, int k) {
        auto ks = t.size();
        if (ks%2 == 0) ks--;
        auto &tmp = t[ks/2];
        tmp += k;
//        cout << t[ks/2] << " " << k <<endl;
        if (tmp < '0') {
            tmp = '9';
            auto i = ks/2-1;
            for (; t[i] == '0'; --i)
                t[i] = '9';
            t[i]--;
        }
        if (tmp > '9') {
            tmp = '0';
            int i = ks/2-1;
            for (; t[i] == '9' && i >= 0; --i)
                t[i] = '0';
            if (i == -1)
                t = '1'+t;
            else t[i]+=1;
        }
        is(t);
        return;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值