形成3的倍数

https://leetcode.cn/problems/largest-multiple-of-three/description/

 

  1. 统计数字信息:

    • 统计每个数字(0-9)出现的次数

    • 统计数字对3取余的结果(0、1、2)的次数

    • 计算所有数字的总和

  2. 处理总和余数:

    • 如果总和能被3整除,直接使用所有数字

    • 如果总和余1,移除1个余1的数字或2个余2的数字

    • 如果总和余2,移除1个余2的数字或2个余1的数字

  3. 构建结果字符串:

    • 从小到大遍历数字,根据移除规则选择保留的数字

    • 处理全0的特殊情况

    • 反转字符串得到降序排列的最大数字

代码详细解析

class Solution {
public:
    string largestMultipleOfThree(vector<int>& digits) {
        vector<int> cnt(10), modulo(3);
        int sum = 0;
        for (int digit: digits) {
            ++cnt[digit]; // 统计每个数字(0-9)出现的次数
            ++modulo[digit % 3]; // 统计数字对3取余的结果(0、1、2)的次数
            sum += digit; // 计算所有数字的总和
        }

        int remove_mod = 0, rest = 0;
        if (sum % 3 == 1) { // 总和余1
            if (modulo[1] >= 1) { // 至少有一个余1的数字
                remove_mod = 1; // 移除1个余1的数字
                rest = 1;
            }
            else { // 没有余1的数字,只能移除2个余2的数字
                remove_mod = 2;
                rest = 2;
            }
        }
        else if (sum % 3 == 2) { // 总和余2
            if (modulo[2] >= 1) { // 至少有一个余2的数字
                remove_mod = 2; // 移除1个余2的数字
                rest = 1;
            }
            else { // 没有余2的数字,只能移除2个余1的数字
                remove_mod = 1;
                rest = 2;
            }
        }

        string ans;
        for (int i = 0; i <= 9; ++i) { // 从小到大遍历数字
            for (int j = 0; j < cnt[i]; ++j) { // 遍历当前数字的所有出现次数
                if (rest && remove_mod == i % 3) { // 如果需要移除当前数字
                    --rest;
                }
                else { // 否则加入结果
                    ans += static_cast<char>(i + '0'); // 数字转字符
                }
            }
        }
        if (ans.size() && ans.back() == '0') { // 处理全0的情况
            ans = "0";
        }
        reverse(ans.begin(), ans.end()); // 反转字符串,变为降序
        return ans;
    }
};

 

posted @ 2025-07-20 18:01  最近饭吃的很多  阅读(8)  评论(0)    收藏  举报