Largest Palindromic Number

Largest Palindromic Number

You are given a string $num$ consisting of digits only.

Return the largest palindromic integer (in the form of a string) that can be formed using digits taken from $num$. It should not contain leading zeroes.

Notes:

  • You do not need to use all the digits of $num$, but you must use at least one digit.
  • The digits can be reordered.

Example 1:

Input: num = "444947137"
Output: "7449447"
Explanation: 
Use the digits "4449477" from "444947137" to form the palindromic integer "7449447".
It can be shown that "7449447" is the largest palindromic integer that can be formed.

Example 2:

Input: num = "00009"
Output: "9"
Explanation: 
It can be shown that "9" is the largest palindromic integer that can be formed.
Note that the integer returned should not contain leading zeroes.

Constraints:

$1 \leq num.length \leq {10}^{5}$
$num$ consists of digits.

 

解题思路

  贪心加分类讨论。

  首先数位肯定是越多越好,然后是首位也是越大越好。因为首位不能是$0$,因此情况分为首位能否填非$0$以外这两种情况。

  首先先开个哈希表统计每一个数出现的次数,先确定最高位可以填什么。从大到小来枚举每个数字$(9 \sim 1)$(注意这里没有$0$),如果某个数的个数大于等于$2$,这意味着首位可以填这个数。如果枚举完发现没有任何一个数字可以填首位,那么意味着非$0$的数都小于$2$,此时整个回文串只能有一个数。这种情况下,再从大到小枚举每个数字$(9 \sim 0)$,如果某个数字存在就直接返回这个数字就好了。

  否则,如果首位可以填非$0$的数,那么意味着中间可以填任何一个数(不管是否含有前导$0$),此时一样从大到小枚举每个数字$(9 \sim 0)$,如果这个数字出现的次数大于等于$2$,那么就一直往后填。

  此时配对的数都填完了,先将字符串反转得到回文存放在一个变量中,然后考虑整个回文串中间的那个数(只有一个),再从大到小枚举每个数字$(9 \sim 0)$,如果某个数字还有(此时个数必然等于$1$),那么就把它填上。最后再把上一步得到的回文进行拼接,然后返回。

  AC代码如下:

 1 class Solution {
 2 public:
 3     string largestPalindromic(string num) {
 4         vector<int> cnt(10);
 5         for (auto &it : num) {
 6             cnt[it - '0']++;
 7         }
 8 
 9         string ans;
10         for (int i = 9; i; i--) {
11             if (cnt[i] >= 2) {
12                 ans = (char)(i + '0');
13                 cnt[i] -= 2;
14                 break;
15             }
16         }
17 
18         if (ans.empty()) {
19             for (int i = 9; i >= 0; i--) {
20                 if (cnt[i]) return to_string(i);
21             }
22         }
23 
24         for (int i = 9; i >= 0; i--) {
25             while (cnt[i] >= 2) {
26                 ans += (char)(i + '0');
27                 cnt[i] -= 2;
28             }
29         }
30 
31         string t(ans.rbegin(), ans.rend());
32         for (int i = 9; i >= 0; i--) {
33             if (cnt[i]) {
34                 ans += (char)(i + '0');
35                 break;
36             }
37         }
38 
39         return ans + t;
40     }
41 };

 

参考资料

  力扣第307场周赛:https://www.bilibili.com/video/BV1KB4y1z7h7

posted @ 2022-08-21 22:00  onlyblues  阅读(22)  评论(0编辑  收藏  举报
Web Analytics