zoukankan      html  css  js  c++  java
  • leetcode 564. Find the Closest Palindrome

    leetcode564题目地址

    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:

    1. The input n is a positive integer represented by string, whose length will not exceed 18.
    2. If there is a tie, return the smaller one as answer

    给定一个字符串。输出离他最近的回文数字,本题中最近的意思是绝对值最小的。

    回文应该很熟悉了把,就是以最中间的数字为对称点对称的数字。

    思路:

    1.理解一下可以发现,题目只有5个candidate数字。将最中间的数字+1,+0,-1然后构造回文数字,因为要尽可能里原来的数字近,只要将左边依次赋值给右边就好了。

    这里可以构造出三个candidate。但是中间数字为0时,-1的时候会出现特殊情况;中间数字为9,+1的时候会出现特殊情况;这两种情况就是下面讨论的。

    2.还有两种可能比较特别。如1001这种,就是中间数字为零的情况,上面的方法-1的情况构造出来就是99。但是答案明明是999。所以我们构造一个比原来位数小一位最大的回文,999作为candidate。 还有一种情况就是999的情况,答案应该是1001.上面的方法中+1的方法构造出来的是100001.显然不对。所以我们够一个比原来位数大一位最小的回文。这是另外两个candidates

    其实思路只有一个,就是将中间数字+1,+0,-1的情况讨论,另外两个只是对数字越出极限的讨论整理。

    注意:

    1.题目中要求的回文是不能跟原来的数字一样的,也就是距离为零是不行的。

    2.NOTE1中要求数字最长为18位,所以应该用long

    3.距离一样取小的那个。

    class Solution {
    public:
        //已知一半构造回文另一半的函数
        string other(string p,int l){
            string other="";
            int len=p.length();
            for(int i=len-1-(l&1);i>=0;i--)
              other+=p[i];
            return other;
        }
        string nearestPalindromic(string n) {
            int l=n.length();
            set<long> cand;
            //构造比原来位数大一位的最小回文
            cand.insert(long(pow(10,l))+1);
            //构造比原来位数小一位的最大回文
            cand.insert(long(pow(10,l-1))-1);
            long mid=stol(n.substr(0,(l+1)/2));
             //-1,+0,+1三种情况
            for(int i=-1;i<=1;i++){
                string p=to_string(mid+i);
                string pp=p+other(p,l);
                cand.insert(stol(pp));
            }
            
            long num = stol(n), minDiff = LONG_MAX, diff, minVal;
            //除去原来的数字
            cand.erase(num);
            for ( long val : cand ) {
                diff = abs(val - num);
                if ( diff < minDiff ) {
                    minDiff = diff;
                    minVal = val;
                } else if ( diff == minDiff ) {
                    minVal = min(minVal, val);
                }
            }
            return to_string(minVal);
        }
    };

    ps:以前在32位机器上int,long的取值范围是一样的。现在64位机器上,int占4字节-2^31~2^31+1,long占8字节,long数据范围变为:-2^63~2^63-1。

  • 相关阅读:
    SIMULINK动态仿真集成环境
    自带计算器
    零知识证明
    2012年软件大赛校内选拔赛
    使用VC2005 Express版时找不到msvcr80d.dll文件
    DirectX 90 3D SetRenderState 设置渲染状态
    ofstream和ifstream详细用法
    IncrediBuild 进行联合编译
    环形缓冲区,魔戒lordrings,boost的circular_buffer
    vector中resize和reserve接口的异同
  • 原文地址:https://www.cnblogs.com/weedboy/p/6848662.html
Copyright © 2011-2022 走看看