题目描述
给你一个整数数组 digits,你能够经过按任意顺序链接其中某些数字来造成 3 的倍数,请你返回所能获得的最大的 3 的倍数。node
因为答案可能不在整数数据类型范围内,请以字符串形式返回答案。c++
若是没法获得答案,请返回一个空字符串。git
示例1web
输入: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 -
返回的结果不该包含没必要要的前导零。
题解
首先要知道一个小学生都知道的定理:若是一个数能够被 整除,那么它的每一位上的数之和也能够被 整除,反之也成立。svg
那么问题就转化为了挑选出最多的数,使得和是 的倍数。咱们能够先求出全部数之和,记为 ,而后有以下三种状况:学习
-
若是 ,那么全部数都选中就好了。 -
若是 ,那么必须删掉一个模 余 的数(按照从小到大顺序删除 一、四、7)。若是这三个数都没有,那就要删除两个模 余 的数(按照从小到大顺序删除 二、五、8,删除两次)。 -
若是 ,那么必须删掉一个模 余 的数(按照从小到大顺序删除 二、五、8)。若是这三个数都没有,那就要删除两个模 余 的数(按照从小到大顺序删除 一、四、7,删除两次)。
最终将剩下的数按照从小到大顺序排序,拼接在一块儿就好了。
注意若是有前导 ,就说明答案就是 。
时间复杂度为 。
代码
c++
class Solution {public: int del(vector<int>& cnt, int q) { for (int i = 0; i <= 9; ++i) { if (i%3 == q && cnt[i]) { return --cnt[i]; } } return -1; }
string largestMultipleOfThree(vector<int>& digits) { vector<int> cnt(10, 0); int sum = 0; for (auto x : digits) { cnt[x]++; sum += x; } int q = sum % 3; if (q && del(cnt, q) < 0) { del(cnt, 3-q); del(cnt, 3-q); } string res = ""; for (int i = 9; i >= 0; --i) { while (cnt[i]--) { res += i+'0'; } } if (res.size() && res[0] == '0') return "0"; return res; }};
做者简介:godweiyang,知乎同名,华东师范大学计算机系硕士在读,方向天然语言处理与深度学习。喜欢与人分享技术与知识,期待与你的进一步交流~
个人微信:weiyang792321264。有任何问题均可以在评论区留言,也欢迎加我微信深刻沟通~
本文分享自微信公众号 - 算法码上来(GodNLP)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。