力扣1363——形成三的最大倍数

给你一个整数数组 digits,你可以通过按任意顺序连接其中某些数字来形成 3 的倍数,请你返回所能得到的最大的 3 的倍数。

由于答案可能不在整数数据类型范围内,请以字符串形式返回答案。

如果无法得到答案,请返回一个空字符串。

 

示例 1:

输入:digits = [8,1,9]
输出:"981"

示例 2:

输入:digits = [8,6,7,1,0]
输出:"8760"

示例 3:

输入:digits = [1]
输出:""

示例 4:

输入:digits = [0,0,0,0,0,0]
输出:"0"

 

提示:

  • 1 <= digits.length <= 10^4
  • 0 <= digits[i] <= 9
  • 返回的结果不应包含不必要的前导零。

题解

这道题讨论的是三的倍数,而我们知道一个数是不是三的倍数,只需要看这个数的各个位数的和是不是三的倍数就可以。
那么,我们可以将输入的每个数字分为三类[0,3,6,9] [1,4,7] [2,5,8],对3求余的结果分别是0 1 2,后面以0类 1类 2类表示
因此我们只需要考虑这三类数字的个数之间的关系就可以了
创建了三个队首为最大值的优先队列 分别是q q1 q2,初始里面装的内容分别是 0 1 2这三类数字
首先,0类数字可以无脑放到最后需要输出的内容中,1类和2类则需要考虑二者的个数关系进行调整,将里面的数字放入到q中
所以最后q中的数字就是我们需要的了
不要忘记考虑一种情况,就是给定的数字是多个0,那么只要返回"0"就可以了
对了,这道题主要是想办法在可以搞出最多个数的数字的情况下,尽可能使每个数字更大
令size1表示1类个个数,size2表示2类的个数,关系图如下所示

代码

点击查看代码
class Solution {
public:
    string largestMultipleOfThree(vector<int>& digits) {
        priority_queue<int> q,q1,q2;

        for(int i = 0;i < digits.size();i++){
            if(digits[i] % 3 == 0) q.push(digits[i]);
            else if(digits[i] % 3 == 1) q1.push(digits[i]);
            else q2.push(digits[i]);
        }

        int size1 = q1.size(),size2 = q2.size();

       /* for(int i = 0; i < size1; i++) {
            cout<<q1.top();
            q1.pop();
        }
        cout<<endl;
        for(int i = 0; i < size2; i++) {
            cout<<q2.top();
            q2.pop();
        }

        cout<<endl;
        return "0";*/

        
        if(size1 == size2){ //如果q1 和 q2一样多,则直接一一配对就可以了
            for(int i = 0;i < size1; i++){
                q.push(q1.top());
                q.push(q2.top());
                //cout<<q1.top()<<" "<<q2.top()<<endl;
                q1.pop();
                q2.pop();
                //cout<<q1.size()<<" "<<q2.size()<<endl;
            }
        }
        else if(size1 > size2){ //q1的数量大于q2
            int diff = ( size1 - size2 ) % 3;
            if(diff == 0){ // 将二者都放进去
                 for(int i = 0;i < size1; i++){
                    q.push(q1.top());
                    q1.pop();
                }
                for(int i = 0;i < size2; i++){
                    q.push(q2.top());
                    q2.pop();
                }

            }
            else if (diff == 1){ // q1都下一个,剩下都放进去  q2都放进去
                 for(int i = 0;i < size1 - 1; i++){
                    q.push(q1.top());
                    q1.pop();
                }
                for(int i = 0;i < size2 ; i++){
                    q.push(q2.top());
                    //cout<<q2.top()<<endl;
                    q2.pop();
                }
            }
            else{ // 
                //
                /*int k = size1 / 3 * 3;
                for(int i = 0 ;i < k ;i++){
                    q.push(q1.top());
                    q1.pop();
                }
                k = size2 / 3 * 3;
                for(int i = 0 ;i < k ;i++){
                    q.push(q2.top());
                    q2.pop();
                }
                while(q1.size() > 0 && q2.size() > 0){
                    q.push(q1.top());
                    q.push(q2.top());
                    q1.pop();
                    q2.pop();
                }*/

                if(size2 == 0){
                    for(int i = 0 ;i < size1 - 2; i++){
                        q.push(q1.top());
                        q1.pop();
                    }

                }
                else{
                    for(int i = 0;i < size1; i++){
                        q.push(q1.top());
                        q1.pop();
                    }
                    for(int i = 0; i < size2 - 1; i++){
                        q.push(q2.top());
                        q2.pop();
                    }
                }


            }
        }
        else{ // q2 > q1
            int diff = ( size2 - size1 ) %3;
            if(diff == 0){//将二者都放进去
                for(int i = 0;i < size1; i++){
                    q.push(q1.top());
                    q1.pop();
                }
                for(int i = 0;i < size2; i++){
                    q.push(q2.top());
                    q2.pop();
                }
            }
            else if(diff == 1){
                for(int i = 0;i < size1; i++){
                    q.push(q1.top());
                    q1.pop();
                }
                for(int i = 0;i < size2 - 1; i++){
                    q.push(q2.top());
                    q2.pop();
                }
            }
            else{
                if(size1 == 0){
                    for(int i = 0;i < size2 - 2;i++){
                        q.push(q2.top());
                        q2.pop();
                    }
                }
                else{
                    for(int i = 0; i < size2;i++) {
                        q.push(q2.top());
                        q2.pop();
                    }
                    for(int i = 0; i < size1 - 1; i++){
                        q.push(q1.top());
                        q1.pop();
                    }
                }
            }
        }


        if(q.size() == 0) return "";
        else {
            string ans;
            if(q.top() == 0) return "0";
            while(q.size() > 0){
                ans += ('0' + q.top());
                //cout<<q.top()<<endl;
                q.pop();
            }
            return ans;
        }
    }
};

简单题解

上面的题解是我的第一想法,当我把这个想法实现之后,突然发现自己想复杂了
我们可以直接对给的所有数字进行相加得到结果res
然后可以分为三种情况进行讨论

  • 1 res % 3 == 0,此时我们可以直接将所有数字直接按照从大到小输出就行
  • 2 res % 3 == 1,此时存在两种情况
    • 1 size1 == 0,此时只需要让2类数字留下最小的两个,剩下都输出
    • 2 size1 != 0,此时只需要让1类数字留下最小的一个,剩下都输出
  • 3 res % 3 == 2,此时存在两种情况
    • 1 size2 == 0,此时让1类留下两个,剩下都输出
    • 2 size2 != 0,此时让2类留下一,剩下都输出就可以

代码

点击查看代码
class Solution {
public:
    string largestMultipleOfThree(vector<int>& digits) {
        priority_queue<int> q,q1,q2;

        for(int i = 0;i < digits.size();i++){
            if(digits[i] % 3 == 0) q.push(digits[i]);
            else if(digits[i] % 3 == 1) q1.push(digits[i]);
            else q2.push(digits[i]);
        }

        int size1 = q1.size(),size2 = q2.size();

        if((size1 + size2 * 2) % 3 == 0){
            for(int i = 0;i < size1; i++){
                q.push(q1.top());
                q1.pop();
            }
            for(int i = 0;i < size2; i++){
                q.push(q2.top());
                q2.pop();
            }
        }
        else if((size1 + size2 * 2) % 3 == 1){
            if(size1 == 0){
                for(int i = 0; i < size2 - 2; i++){
                    q.push(q2.top());
                    q2.pop();
                }
            }
            else{
                for(int i = 0; i < size1 - 1; i++){
                    q.push(q1.top());
                    q1.pop();
                }
                for(int i = 0; i < size2; i++){
                    q.push(q2.top());
                    q2.pop();
                }
            }
        }
        else{
            if(size2 == 0){
                for(int i = 0; i < size1 - 2; i++){
                    q.push(q1.top());
                    q1.pop();
                }
            }
            else{
                for(int i = 0; i < size1; i++){
                    q.push(q1.top());
                    q1.pop();
                }
                for(int i = 0; i < size2 - 1; i++){
                    q.push(q2.top());
                    q2.pop();
                }
            }
        }

        if(q.size() == 0) return "";
        else {
            string ans;
            if(q.top() == 0) return "0";
            while(q.size() > 0){
                ans += ('0' + q.top());
                //cout<<q.top()<<endl;
                q.pop();
            }
            return ans;
        }

    }
};
posted @ 2022-09-21 20:30  白菜茄子  阅读(53)  评论(0编辑  收藏  举报