给定一个整数 n ,你需要找到与它最近的回文数(不包括自身)。
“最近的”定义为两个整数差的绝对值最小。
示例 1:
输入: "123"
输出: "121"
注意:
n 是由字符串表示的正整数,其长度不超过18。
如果有多个结果,返回最小的那个。
基础思路:
- n的中间位,如果n为奇数,中间位是 n .length/ 2 - 0.5;如果为偶数,其实是没有中间位,但是在实际修改时,中间位是 2个: n .length/ 2和 n.length/ 2 - 1
- n的几种可能性 和 基本结果
问题:
n的长度 <= 18, 而js不支持这么大位数的计算
解决:
除了n不是回文数且不是10的n次幂的情况都用字符串做判断
n不是回文数且不是10的n次幂的情况下, 因为只有n的后半部分做了改变,所以只需要
Math.floor(n.length/2 )位数 加减。但还需要考虑otherX的情况,otherX 可能会是
x加或者减 10的 Math.floor(n.length/2 )次幂,所以最后计算位数为 Math.floor(n.length/2 ) + 1
代码(很挫而且很~~~~~大一坨,还没有注释,也没做过优化,还是js版)
/**
- @param {string} n
- @return {string}
*/
var nearestPalindromic = function(n) {
if( n.length === 1 ){
return (parseInt( n ) - 1).toString()
}
let len = n.length
let isOdd = len % 2 === 0 ? false : true
let c = Math.floor(len / 2)
let s1 = n.slice(0 , (len % 2 === 0 ? len /2 : len / 2 - 0.5));
let s2 = n.slice( len % 2 === 0 ? len /2 : len / 2 + 0.5 )
let s1R = s1.split('').reverse().join('')
let s2R = s2.split('').reverse().join('')
let same = true
let isZero = true
let isNine= true
for( let i = 1 ; i < n.length ; i++){
if(n[i-1] !== n[i]) same = false
if( i !== n.length - 1 && n[i] !== '0'){
isZero = false
}
if( n[i] != 9){
isNine= false
}
}
if( (n[0] === '1' && n[n.length - 1] === '1' && isZero) ||(n[0] === '1' && n[n.length - 1] === '0' && isZero) ){
let str = ''
for( let i = 0 ; i < n.length-1 ; i++){
str += '9'
}
return str
}
if( same && n[0] === '9'){
let str = '1'
for( let i = 0 ; i < n.length - 1 ; i++){
str += '0'
}
return str + '1'
}
if( isNine ){
let str = 1 + n[0] * 1
for( let i = 0 ; i < n.length - 2 ; i++){
str += '0'
}
return str + ( 1 + n[0] * 1)
}
if( s1 === s2R ){
let s = n
if( n[c] === '0'){
if( isOdd ){
s = s1 + '1' + s2
}else{
s = s1.slice(0, -1) + 1 + 1 + s2.slice(1)
}
}else if(n[c] === '9'){
let nowL = (s1 * 1 + 1).toString()
let nowR = nowL.split('').reverse().join('')
if(isOdd){
if( n[c-1] !== '9'){
return s = s1 + (n[c] - 1) + s2
}
return nowL + 0 + nowR
}
return nowL + nowR
}else{
if( isOdd ){
s = s1 + (n[c] - 1) + s2
}else{
s = s1.slice(0, -1) + (n[c] - 1)+ (n[c] - 1) + s2.slice(1)
}
}
return s
}else{
let now = parseInt(n[isOdd ? c : c -1 ] + s1R)
let old = parseInt(n[isOdd ? c : c -1 ] + s2)
let otherNow = 0
let num = Math.pow(10, c)
if( !isOdd ){
num += (c - 1 === 0 ? 1 : Math.pow( 10, c - 1))
}
if(now > old){
otherNow = now - num
}else{
otherNow = now + num
}
let otherNowS = otherNow, nowS = now
let zeroO = Math.floor(len / 2) + 1 - otherNow.toString().length
let zeroN = Math.floor(len / 2) + 1 - now.toString().length
for( let i = 0 ; i < zeroO ; i++){
otherNowS = '0' + otherNow
}
for( let i = 0 ; i < zeroN ; i++){
nowS = '0' + nowS
}
if(Math.abs(old - now) > Math.abs(old - otherNow)){
return isOdd ? s1 + otherNowS : s1.slice(0, -1) + otherNowS
}else if (Math.abs(old - now) === Math.abs(old - otherNow)){
let rNow = otherNow > now ? nowS : otherNowS
return isOdd ? s1 + rNow : s1.slice(0, -1) + rNow
}else{
return isOdd ? s1 + nowS : s1.slice(0, -1) + nowS
}
}
};
结尾吐槽:
这道题现在在leetcode上,等级为困难,通过率7.7%,但感觉好多简单里的题都比它难。
再一个感觉自己这篇博客也没写明白啊,要是我看到这种东西肯定就骂街了,得再思考着改改呜呜呜
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。