給定一個整數 n ,你須要找到與它最近的迴文數(不包括自身)。優化
「最近的」定義爲兩個整數差的絕對值最小。spa
示例 1:rest
輸入: "123"
輸出: "121"
注意:code
n 是由字符串表示的正整數,其長度不超過18。
若是有多個結果,返回最小的那個。圖片
基礎思路:leetcode
問題:字符串
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版)string
/**
*/it
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%,但感受好多簡單裏的題都比它難。
再一個感受本身這篇博客也沒寫明白啊,要是我看到這種東西確定就罵街了,得再思考着改改嗚嗚嗚