564. Find the Closest Palindrome (Hard)

来源:互联网 发布:oracle 创建同义词sql 编辑:程序博客网 时间:2024/06/10 08:48

原题目:
  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.

题目大意如下:
  给定一个整数,找到它“最近”的回文整数,“最近”定义为数值之间差的绝对值最小。
  注意:
  1.整数由string的形式给出;
  2.如果有距离相等的多个数,选择最小的那个。

解题思路:
  首先,我们要理解Palindrome的含义:
  回文,可以看做是将字符串左半部分进行倒转然后覆盖到右半部分,因此我们只需要关注左半部分。
  举个例子:str = 123456
  我们取左半部分substr = 123,题目要求“距离最短”显然,越左代表位数越高差值越大,所以我们考虑最右边的一个数(即原字符串中间的数)。substr1=124,substr2=122,至此我们可以得到3个候选string:
  candidate1 = 12321;
  candidate2 = 12421;
  candidate3 = 12221;
  还没完,如果例子为:88或者10
  显然相对应的我们应该返回101或者9,所以我们应该加入比原字符串多一位的100……001和比原字符串少一位的99……99作为候选
  最后,我们选择candidate数组当中和原数值差值最小的返回就可以了。

代码如下:

class Solution {public:    string nearestPalindromic(string n) {        if(n.empty()) return n ;        if(n.size() == 1){            n[0] -= 1 ;            return n ;        }        vector<string> cand ;        //比n少一位的“99……99”        cand.push_back(string(n.size() - 1 , '9')) ;        //比n多一位的“10000……00001”        string str = n ;        str[0] = '1' ;        for(int i = 1 ; i < str.size() ; ++i)            str[i] = '0' ;        str.push_back('1') ;        cand.push_back(str) ;        //把原字符串变为Palindrome        str = n ;        cand.push_back(make_pa(str)) ;        //把中间字符加一变为Palindrome        int mid = (str.size() - 1)/2 ;        str[mid] += 1 ;        //把中间字符减一变为Palindrome        cand.push_back(make_pa(str)) ;        str[mid] -= 2 ;        cand.push_back(make_pa(str)) ;        //选取距离最近的那个候选字符串        long diff = INT_MAX , mark = 0 , temp ;        for(int i = 0 ; i < cand.size() ; ++i){            temp = make_diff(cand[i] , n) ;            if(temp > 0 && temp < diff){                mark = i ;                diff = temp ;            }            //如果有等距离的,取小的那个            else if(temp > 0 && temp == diff){                if(atol(cand[i].c_str()) < atol(cand[mark].c_str())) mark = i ;            }        }        return cand[mark] ;    }    //字符串转变为数值然后做差    long make_diff(string s , string n){        long count_s = atol(s.c_str()) , count_n = atol(n.c_str()) ;        return abs(count_s - count_n) ;    }    //将字符串变为Palindrome    string make_pa(string str){        for(int i = str.size() - 1, j = 0 ; i > (str.size() - 1)/2 ; --i , ++j)            if(str[i] != str[j]) str[i] = str[j] ;        return str ;    }};

运行结果:
运行结果

知识补充:
1.头文件stdlid.h中函数:
 atoi
 原型:int atoi (const char * str);
 将ascll码(c_string)转换成int类型,因为参数要c_string的头指针所以可以配合strng中的c_str()函数。
 于此同类的函数:atol(返回long int),atoll(返回long long int),atof(返回double)
 例:

long count_s = atol(s.c_str()) , count_n = atol(n.c_str()) ;

2.string中的to_string函数:
string to_string (int val);
string to_string (long val);
string to_string (long long val);
string to_string (unsigned val);
string to_string (unsigned long val);
string to_string (unsigned long long val);
string to_string (float val);
string to_string (double val);
string to_string (long double val);

0 0
原创粉丝点击