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

xiaoyongyong發表於2024-11-22
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:

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);
    }
}

2468. Split Message Based on Limit

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;
    }
}

相關文章