Lc第307场周赛 6166. 最大回文数字(贪心/分类讨论)

题目链接:https://leetcode.cn/problems/largest-palindromic-number/

题目描述

给你一个仅由数字(0 - 9)组成的字符串 num 。

请你找出能够使用 num 中数字形成的 最大回文 整数,并以字符串形式返回。该整数不含 前导零 。

注意:

你 无需 使用 num 中的所有数字,但你必须使用 至少 一个数字。
数字可以重新排序。

 

示例 1:

输入:num = "444947137"
输出:"7449447"
解释:
从 "444947137" 中选用数字 "4449477",可以形成回文整数 "7449447" 。
可以证明 "7449447" 是能够形成的最大回文整数。
示例 2:

输入:num = "00009"
输出:"9"
解释:
可以证明 "9" 能够形成的最大回文整数。
注意返回的整数不应含前导零。

 

提示:

1 <= num.length <= 105
num 由数字(0 - 9)组成

 

思路 

        先讨论回文串的前一半,用从首位开始枚举最大的数字,然后再往后一个个贪心枚举最大数字。枚举完前一半字符串后,反转该字符串并与原来的字符串拼接。由于答案要尽可能大,所以位数要尽可能多,因此在回文串正中间也要再拼上一位数字。

C++代码

class Solution {
public:
    string largestPalindromic(string num) {
        int cnt[11] = {};
        string res = "";
        for(char i : num) ++cnt[i - '0'];

        //先讨论前一半字符串的首位,注意不含0
        for(int i = 9; i > 0; i--){
            if(cnt[i] >= 2){
                res += to_string(i);
                cnt[i] -= 2;  //要构成回文,肯定有大于等于2个该数字
                break;  //注意别忘了及时break掉,不然答案会错
            }
        }

        //字符串为空,说明整个字符串只有0或者单个其它数字
        if(res == "")
            for(int i = 9; i >= 0; i--)    
                if(cnt[i]) return to_string(i);

        //讨论完首位,把余下来的位置(该回文串的前一半)讨论完
        for(int i = 9; i >= 0; i--){
            while(cnt[i] >= 2){
                res += to_string(i);
                cnt[i] -= 2;
            }
        }

        //反转前一半字符串,拼接在一起作为结果输出
        string ans = string(res.rbegin(), res.rend());

        //因为回文串位数越多越好,所以还有没用掉的数字的话,可以加一位在回文串的正中间
        for(int i = 9; i >= 0; i--) 
            if(cnt[i]){
                res += to_string(i);    
                break;
            } 

        return res + ans;
    }
};

你可能感兴趣的:(Leetcode,leetcode,贪心算法,算法,数据结构)