回溯法 解 1363 形成三的最大倍数

简介

虽然超时了, 但是我还是想把这种思想放在这里. 这肯定可以做(现在是回溯增加), 改为回溯减少一定就可以了.

参考链接

https://leetcode-cn.com/problems/largest-multiple-of-three/solution/c-qu-diao-zui-xiao-zhi-8ms-by-yusenzhang_chatc/

算法思路

如果取模3等于0,那其实可以都要,如果是1,那就得去掉一个1或者两个2,如果是2那就得去掉一个2或者两个1.
而这些删掉一个数的函数其实是类似的,可以反复调用。
注意在如果全是0输出0而不是00000. 删完数之后判断答案的最高位是不是0即可。
学习一下JOHNKRAM的压行操作

code

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Solution {
public:
    void dfs(vector<int> &candidates, vector<int> &ans, vector<int> &combine, int idx) {
        if(idx >= candidates.size()) {
            return;
        }
        // 直接跳过
        dfs(candidates, ans, combine, idx + 1);

        
        // 选择当前数
        combine.emplace_back(candidates[idx]);
                vector<int> tmp;
        tmp.assign(combine.begin(), combine.end());
        sort(tmp.begin(), tmp.end(), greater<int>());
        int sumAdd = 0;
        for(auto it: tmp){
            sumAdd += it;
        }
        
        if(sumAdd % 3 == 0) {
            string s1;
            for(auto it : tmp){
                s1 += it + '0';
            }
            string s2;
            for(auto it : ans){
                s2 += it + '0';
            }
            if(s1.size() > s2.size()){
                ans.clear();
                ans.assign(tmp.begin(), tmp.end());
            }else if(s1.size() == s2.size()){
                if(s1 > s2) {
                    ans.clear();
                    ans.assign(tmp.begin(), tmp.end());
                }
            }
        }
        dfs(candidates, ans, combine, idx+1);
        combine.pop_back();
        //cout << idx ;
    }
    string largestMultipleOfThree(vector<int>& digits) {
        vector<int> ans;
        vector<int> combine;
        dfs(digits, ans, combine, 0);
        string s2;

        for(auto it : ans){
            s2 += it + '0';
        }
        if(ans.size() > 0  && ans[0] == 0){
            return "0";
        }
        return s2;
    }
};
int main() {
    Solution s;
    int a [] = {0,0,0,0,0,0};
    vector<int> t;
    t.assign(a, a+6);
    cout << s.largestMultipleOfThree(t);
    // string c = "123";
    // string d = "43";
    // if(c > d){
    //     cout << c;
    // }
    return 0;
}
class Solution {
    int cnt[10],sum;
    string ans = "";
    int del(int m)
    {
        for(int i=m;i<=9;i+=3)if(cnt[i]){cnt[i]--;return 1;}
        return 0;
    }
public:
    string largestMultipleOfThree(vector<int>& d) {
        for(auto x:d)cnt[x]++,sum+=x;
        if(sum%3==1)if(!del(1))del(2),del(2);
        if(sum%3==2)if(!del(2))del(1),del(1);
        for(int i=9;i>=0;i--)while(cnt[i]--)ans+=i+'0';
        if(ans.size() && ans[0] == '0') return "0";
        return ans;
    }
};

TIPS

JOHNKRAM的压行操作,
可以参考下面这篇博客. 压行, 对于思路清晰的人来说, 还是很清晰的.
https://blog.csdn.net/KonnyWen/article/details/104564233

Hope is a good thing,maybe the best of things,and no good thing ever dies.----------- Andy Dufresne
原文地址:https://www.cnblogs.com/eat-too-much/p/14782870.html