564. Find the Closest Palindrome
Given a string n
representing an integer, return the closest integer (not including itself), which is a palindrome. If there is a tie, return the smaller one.
The closest is defined as the absolute difference minimized between two integers.
Example 1:
Example 2:
Input: n = "1"
Output: "0"
Explanation: 0 and 2 are the closest palindromes but we return the smallest which is 0.
Constraints:
1 <= n.length <= 18
n
consists of only digits.n
does not have leading zeros.n
is representing an integer in the range[1, 1018 - 1]
.
Solution:
class Solution {
public String nearestPalindromic(String n) { // n = "12345"
int len = n.length(); // 5
int i = 0;
if (len % 2 == 0){ // even 5 % 2 ! =0
i = len/2 -1;
}else {
i = len/2; // i = 2
}
long firstHalf = Long.parseLong(n.substring(0, i + 1));
// n.substring(0, 2 + 1) = n.substring(0, 3)
// 12 3
/*
Generate possible palindromic candidates:
1. Create a palindrome by mirroring the first half
2. Create a palindrome by mirroring the first half incremented by 1.
3. Create a palindrome by mirroing the first half decremented by 1.
4. Handle edge case by considering palindromes of the form 999...
and 100....001(smallest and largest n - digit palindromes).
*/
List<Long> possibilities = new ArrayList<>();
possibilities.add(halfToPalindrome(firstHalf, len % 2 == 0)); // 123, F
possibilities.add(halfToPalindrome(firstHalf + 1, len % 2 == 0)); // 124, F
possibilities.add(halfToPalindrome(firstHalf - 1, len % 2 == 0)); // 122, F
possibilities.add((long) Math.pow(10, len - 1) - 1); // Math.pow(10, 5-1 ) - 1 = 10^4 - 1 = 9999
possibilities.add((long) Math.pow(10, len) + 1);// Math.pow(10, 5) + 1 =10^5 + 1= 100000+1=100001
// Find the palindrome with minimum difference, and minimum value.
long diff = Long.MAX_VALUE;
long res = 0;
long nl = Long.parseLong(n);// 12345
for (long cand : possibilities){ //
if (cand == nl){
continue;
}
if (Math.abs(cand - nl) < diff){
diff = Math.abs(cand - nl);
res = cand;
}else if (Math.abs(cand - nl) == diff){
res = Math.min(res, cand);
}
}
return String.valueOf(res);
}
private long halfToPalindrome(long left, boolean even){ // 123, F
// Convert the given half to palindrome.
long res = left; // 123
if (!even){ // F
left = left / 10; // 123/ 10 = 12
}
while(left > 0){ // 123>0
res = res * 10 + (left % 10); // 123 * 10 + 12 %10 = 1230 + 2 1232// 1232 * 10 + (2%2 ) =12321
left = left / 10; // 12 / 10 =1; // 0
}
// 好一个人类, 这是咋想出来的, 感觉在玩数字...
return res;
// 12321
}
}
// TC: O(n)
// SC: O(n)
class Solution {
public String nearestPalindromic(String n) {
if (n.length() == 1){
String result = Character.toString(n.charAt(0) - 1);
return result;
}
int left = 0;
int right = n.length() - 1;
/*
012
121
l r
0 2
*/
char[] nArray = n.toCharArray();
while(left < right - 1){//0<2-1
if (nArray[left] == nArray[right]){
left++;
right--;
}else{
nArray[right] = nArray[left];
left++;
right--;
}
}
// 12 3 4
// l r
// l r
//
// 3 3 3
//
if (left == right){
// if (n.charAt(right + 1) > nArray[right + 1]){
return new String(nArray);
//}
}else{
// if (n.charAt(left) < n.charAt(right)){
// nArray[right] = n.charAt(left);
// }else{
// nArray[left] = n.charAt(right);
// }
nArray[right] = n.charAt(left);
return new String(nArray);
}
/* 1 2 3 1
l
r
l r
*/
/*
123
>1 2 1 <
*/
}
}
// 处理边界值卡了
?/?