564. Find the Closest Palindrome, 2468. Split Message Based on Limit

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:

Input: n = "123"
Output: "121"

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].
class Solution {
    public String nearestPalindromic(String n) {
        // 特殊情况处理
        if(n.equals("1")) return "0";
        // 
        long original  = Long.parseLong(n);
        long small = Long.parseLong(smaller(n));
        long big = Long.parseLong(bigger(n));
        return original - small <= big - original ? ("" + small) : ("" + big);
    }
    private String smaller(String s) {
        // 转换为array便于处理
        char[] arr = s.toCharArray();
        // 从两侧到中间,对称
        int l = 0, r = arr.length - 1;
        while(l < r) {
            arr[r--] = arr[l++];
        }
        // 如果当前已经是smaller那么直接返回
        String result = new String(arr);
        if(result.compareTo(s) < 0) {
            return result;
        }
        // 否则的话需要重新计算
        arr = s.toCharArray();
        // 找到中间点
        int mid = (s.length() - 1) / 2;
        int carry = 1;
        // 从中间元素-1得到smaller
        for(int i = mid; i >= 0; i--) {
            int t = 0;
            if(atoi(arr[i]) - carry >= 0) {
                t = atoi(arr[i]) - carry;
                carry = 0;
            }
            else {
                t = 9;
            }
            arr[i] = itoa(t);
            arr[s.length() - i - 1] = itoa(t);
        }
        // 如果第一位是0,说明减去之后位数直接少了,那么直接返回这个位数的最大,比如:9999
        if(arr[0] == '0') return biggest(s.length() - 1);
        return new String(arr);
    }

    private String bigger(String s) {
        char[] arr = s.toCharArray();
        int l = 0, r = arr.length - 1;
        while(l < r) {
            arr[r--] = arr[l++];
        }
        String result = new String(arr);
        if(result.compareTo(s) > 0) {
            return result;
        }
        arr = s.toCharArray();
        int mid = (s.length() - 1) / 2;
        int carry = 1;
        for(int i = mid; i >= 0; i--) {
            int t = 0;
            if(atoi(arr[i]) + carry <= 9) {
                t = atoi(arr[i]) + carry;
                carry = 0;
            }
            else {
                t = 0;
            }
            arr[i] = itoa(t);
            arr[s.length() - i - 1] = itoa(t);
        }
        if(carry == 1) return smallest(s.length() + 1);
        return new String(arr);
    }

    private String smallest(int count) {
        char[] arr = new char[count];
        Arrays.fill(arr, '0');
        arr[0] = '1';
        arr[arr.length - 1] = '1';
        return new String(arr);
    }
    private String biggest(int count) {
        char[] arr = new char[count];
        Arrays.fill(arr, '9');
        return new String(arr);
    }
    private int atoi(char c) {
        return (int)(c - '0');
    }
    private char itoa(int i){
        return (char)('0' + i);
    }
}

 

You are given a string, message, and a positive integer, limit.

You must split message into one or more parts based on limit. Each resulting part should have the suffix "<a/b>", where "b" is to be replaced with the total number of parts and "a" is to be replaced with the index of the part, starting from 1 and going up to b. Additionally, the length of each resulting part (including its suffix) should be equal to limit, except for the last part whose length can be at most limit.

The resulting parts should be formed such that when their suffixes are removed and they are all concatenated in order, they should be equal to message. Also, the result should contain as few parts as possible.

Return the parts message would be split into as an array of strings. If it is impossible to split message as required, return an empty array.

Example 1:

Input: message = "this is really a very awesome message", limit = 9
Output: ["thi<1/14>","s i<2/14>","s r<3/14>","eal<4/14>","ly <5/14>","a v<6/14>","ery<7/14>"," aw<8/14>","eso<9/14>","me<10/14>"," m<11/14>","es<12/14>","sa<13/14>","ge<14/14>"]
Explanation:
The first 9 parts take 3 characters each from the beginning of message.
The next 5 parts take 2 characters each to finish splitting message. 
In this example, each part, including the last, has length 9. 
It can be shown it is not possible to split message into less than 14 parts.

Example 2:

Input: message = "short message", limit = 15
Output: ["short mess<1/2>","age<2/2>"]
Explanation:
Under the given constraints, the string can be split into two parts: 
- The first part comprises of the first 10 characters, and has a length 15.
- The next part comprises of the last 3 characters, and has a length 8. 

Constraints:

  • 1 <= message.length <= 104
  • message consists only of lowercase English letters and ' '.
  • 1 <= limit <= 104
class Solution {
    public String[] splitMessage(String message, int limit) {
        // 计算需要的 分片个数
        int count = 0, indLen = 0;
        // indLen 会随着增长变化: 1,2,...9,10,...,99,100
        // </> 是固定的3位
        // count表示总分片数
        // 调整分片数,直到满足条件
        // count+</>+ind 没有超过
        // count足够多,满足:indLen + (3 + len(count)) + message.length() >= limit * count 
        while(3 + ("" + count).length() * 2 < limit // 单个part没有超过limit
            // 总长度还不足以满足
            && indLen + (3 + ("" + count).length()) * count + message.length() > limit * count 
        ) {
            count++;
            indLen += ("" + count).length();
        }

        // 检查是否单个分片满足条件,如果不满足那么说明根本不可能,直接返回空串
        if(3 + ("" + count).length() * 2 >= limit) {
            return new String[0];
        }

        // 开始填充
        String[] result = new String[count];
        int ind = 0;
        for(int i = 1; i <= count; i++) {
            int len = limit - 3 - (""+i).length() - ("" + count).length();
            result[i - 1] 
            = message.substring(ind, Math.min(ind + len, message.length())) + "<" + i + "/" + count + ">";
            ind += len;
        }
        return result;
    }
}

 

posted @ 2024-11-22 08:39  xiaoyongyong  阅读(24)  评论(0编辑  收藏  举报