564 Find the Closest Palindrome

1959 ワード

C++のグループに入ってから、私のJavaは生まれましたが、C++はまだ慣れていません.たまにアルゴリズムの問題をして娯楽をしたいのですが、C++はトラで、問題をブラシすることができなくて少し気まずいです.
この問題は最近の返事数を探して、この問題は基本的に認知能力を試して、あなたの現場で問題を分析して問題を解決する能力を見て、あまり道がありません.法則をよく分析してきれいなcodeを書くことです.最もbrute forceの解法は、私がこの数に沿って上へ行って、それより大きい最初の回文数を見つけて、下へ探して、それより小さい最初の回文数を見つけることです.そして2つ比較してみます.この時間は複雑度が高い.回文数については、構築方法を採用することができます.一つの数に対して真ん中から二つに割って、
  • 1回文数の前半と後半は対称であるため,回文数
  • を合成することができる.
  • 最近の返信数を探す場合は、できるだけ後半と前半matchを変更します.
  • 私達は3つのcandidateがあって、a.前半、+前半反転合成1個数b.前半+1,+(前半+1,反転)合成c.前半-1,+(前半-1,反転)合成
  • 例1:3456 a:3443 b:3553 c:3333
    例2:34567 a:34543 b:34643 c:34443
    しかし、この数が1000であれば、前半が1を引くと9になり、合成数が99になるのは明らかに間違っているので、この場合、最近は数がそれより小さい位のものはすべて9になります.同じように9999も考えなければなりません.
    コードは以下の通り、私にとって最もchallengeの場所はC++バグが発生しやすい場所は奇数のcaseです.
    class Solution {
    public:
        string nearestPalindromic(string n) {
            int len = n.size();
            long nAsNum = stol(n);
            unordered_set s;
            s.insert(pow(10, len) + 1);
            s.insert(pow(10, len - 1) - 1);
            long pre = stol(n.substr(0, (len + 1) / 2));
            
            for (long i = -1; i <= 1; ++i) {
                string prefix = to_string(pre + i);
                s.insert(stol(prefix + string(prefix.rbegin() + (len % 2), prefix.rend())));
            }
            s.erase(nAsNum);
            
            long diff = LONG_MAX;
            long ans = *(s.begin());
            for (long cand : s) {
                if (abs(cand - nAsNum) < diff) {
                    ans = cand;
                    diff = abs(cand - nAsNum);
                } else if (abs(cand - nAsNum) == diff) {
                    ans = min(cand, ans); // cannot combine the two cases together
                }
            }
            return to_string(ans);
        }
    };
    

    学習したC++の知識点はあります
  • substr
  • reverse a string: string(prefix.rbegin(), prefix.rend())
  • stol : convert a string to long
  • LONG_MAX

  • 参考資料:https://www.cnblogs.com/grandyang/p/6915355.html