LC 1363. Largest Multiple of Three (greedy / dp)

link

 

Solution 1 gready:

class Solution {
public:
    string largestMultipleOfThree(vector<int>& digits) {
        multiset<int,greater<int>> one, two;
        int sum=0;
        int r1=-1;
        int r2=-1;
        for(int i:digits){
            sum+=i;
            if(i%3==1){
                one.insert(i);
            }else if(i%3==2){
                two.insert(i);
            }
        }
        if(sum%3==1){
            if(one.size()>0){
                auto it=one.end();
                r1=*(--it);
            }else{
                auto it=two.end();
                r1=*(--it);
                r2=*(--it);
            }
        }else if(sum%3==2){
            if(two.size()>0){
                auto it=two.end();
                r1=*(--it);
            }else{
                auto it=one.end();
                r1=*(--it);
                r2=*(--it);
            }
        }
        
        vector<int> f;
        for(int i:digits){
            if(i==r1){
                r1=-1;
                continue;
            }
            if(i==r2){
                r2=-1;
                continue;
            }
            f.push_back(i);
        }
        sort(f.begin(),f.end(),greater<int>());
        string res="";
        if(f.size()>0 && f[0]==0) return "0";
        for(int i:f){
            res.push_back(i+'0');
        }
        return res;
    }
};

 

Solution 2 dp:

class Solution {
public:
    string largestMultipleOfThree(vector<int>& digits) {
        vector<int> nonzero;
        int cnt0=0;
        for(int i:digits){
            if(i==0) cnt0++;
            else nonzero.push_back(i);
        }
        if(cnt0==digits.size()) return "0";
        sort(nonzero.begin(),nonzero.end(),greater<int>());
        int size=nonzero.size();
        vector<vector<int>> memo(nonzero.size(),vector<int>(3,-1));
        vector<vector<int>> take(nonzero.size(),vector<int>(3,0));
        dfs(0,0,nonzero,memo,take);
        
        string res="";
        int cursum=0;
        for(int i=0;i<nonzero.size();++i){
            if(take[i][cursum]==1){
                res+=to_string(nonzero[i]);
                cursum=(cursum+nonzero[i])%3;
            }
        }
        if(res=="") {
            if(cnt0>0) return "0";
            return "";
        }
        for(int i=0;i<cnt0;++i) res+="0";
        return res;
    }
    
    int dfs(int idx, int cursum,vector<int>& nonzero,vector<vector<int>> &memo, vector<vector<int>> &take){
        if(idx==nonzero.size()) {
            if(cursum==0){
                return 0;
            }
            return INT_MIN;
        }
        if(memo[idx][cursum]!=-1) return memo[idx][cursum];
        
        //untake
        int res=dfs(idx+1,cursum,nonzero,memo,take);
        
        //take
        int next=dfs(idx+1,(cursum+nonzero[idx])%3,nonzero,memo,take);
        if(1+next>=res){
            res=1+next;
            take[idx][cursum]=1;
        }
        return memo[idx][cursum]= res;
    }
};

 

posted @ 2020-02-23 16:23  feibilun  阅读(236)  评论(0编辑  收藏  举报