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