III -- Construct the whole palindrome from its left part
Construct a palindrome based on left half, then find the nearest palindrome larger or smaller than curP: nextP, prevP. Then compare the diff between num, cur, prev, next.
classSolution {publicStringnearestPalindromic(String n) {if (n ==null||n.isEmpty()) {return""; }char[] p =n.toCharArray();for (int i =0, j =p.length-1; i < j; i++, j--) { p[j] = p[i]; }String curP =String.valueOf(p);String prevP =nearestPalindromeOf(curP,false);String nextP =nearestPalindromeOf(curP,true);long num =Long.valueOf(n);long cur =Long.valueOf(curP);long prev =Long.valueOf(prevP);long next =Long.valueOf(nextP);long d1 =Math.abs(num - cur);long d2 =Math.abs(num - prev);long d3 =Math.abs(num - next);if (num == cur) {return d2 <= d3 ? prevP : nextP; } elseif (num > cur) {return d1 <= d3 ? curP : nextP; } else {return d2 <= d1 ? prevP : curP; } } /** * @param s - input palindrome string * @param dir true if finding larger, false if finding smaller * @return nearest palindrome string of input palindrome */publicStringnearestPalindromeOf(String s,boolean dir) {int len =s.length();int k = len /2;// make sure left include the mid point if len is odd numberint base =Integer.valueOf(s.substring(0, len - k)); base += dir ?1:-1;// handle "11", "1" caseif (base ==0) {if (k ==0) {return"0"; }return"9"; }StringBuilder left =newStringBuilder(String.valueOf(base));StringBuilder right =newStringBuilder(left).reverse();// handle "1001", "10001" type of caseif (k >left.length()) {right.append("9"); }returnleft.append(right.substring(right.length() - k)).toString(); }}
LeetCode official
Using Math:
Time complexity : O(l). Scanning, insertion, deletion,, mirroring takes O(l), wherellis the length of the string.
Space complexity : O(l). Temporary variables are used to store the strings.
publicclassSolution {publicStringmirroring(String s) {String x =s.substring(0, (s.length()) /2);return x + (s.length() %2==1?s.charAt(s.length() /2) :"") +newStringBuilder(x).reverse().toString(); }publicStringnearestPalindromic(String n) {if (n.equals("1"))return"0";String a =mirroring(n);long diff1 =Long.MAX_VALUE; diff1 =Math.abs(Long.parseLong(n) -Long.parseLong(a));if (diff1 ==0) diff1 =Long.MAX_VALUE;StringBuilder s =newStringBuilder(n);int i = (s.length() -1) /2;while (i >=0&&s.charAt(i) =='0') {s.replace(i, i +1,"9"); i--; }if (i ==0&&s.charAt(i) =='1') {s.delete(0,1);int mid = (s.length() -1) /2;s.replace(mid, mid +1,"9"); } elses.replace(i, i +1,""+ (char)(s.charAt(i) -1));String b =mirroring(s.toString());long diff2 =Math.abs(Long.parseLong(n) -Long.parseLong(b)); s =newStringBuilder(n); i = (s.length() -1) /2;while (i >=0&&s.charAt(i) =='9') {s.replace(i, i +1,"0"); i--; }if (i <0) {s.insert(0,"1"); } elses.replace(i, i +1,""+ (char)(s.charAt(i) +1));String c =mirroring(s.toString());long diff3 =Math.abs(Long.parseLong(n) -Long.parseLong(c));if (diff2 <= diff1 && diff2 <= diff3)return b;if (diff1 <= diff3 && diff1 <= diff2)return a;elsereturn c; }}