惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

云风的 BLOG
云风的 BLOG
C
Cyber Attacks, Cyber Crime and Cyber Security
Recent Announcements
Recent Announcements
爱范儿
爱范儿
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Security Latest
Security Latest
J
Java Code Geeks
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Cisco Talos Blog
Cisco Talos Blog
Apple Machine Learning Research
Apple Machine Learning Research
C
Check Point Blog
T
Threat Research - Cisco Blogs
I
Intezer
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
WordPress大学
WordPress大学
Engineering at Meta
Engineering at Meta
腾讯CDC
Google DeepMind News
Google DeepMind News
Project Zero
Project Zero
T
Tenable Blog
V
Visual Studio Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
Spread Privacy
Spread Privacy
GbyAI
GbyAI
T
Tailwind CSS Blog
P
Palo Alto Networks Blog
Microsoft Security Blog
Microsoft Security Blog
Scott Helme
Scott Helme
Hugging Face - Blog
Hugging Face - Blog
NISL@THU
NISL@THU
Blog — PlanetScale
Blog — PlanetScale
G
GRAHAM CLULEY
K
Kaspersky official blog
T
The Exploit Database - CXSecurity.com
S
Schneier on Security
P
Proofpoint News Feed
S
SegmentFault 最新的问题
P
Proofpoint News Feed
P
Privacy & Cybersecurity Law Blog
The Hacker News
The Hacker News
博客园 - 【当耐特】
Cyberwarzone
Cyberwarzone
L
LangChain Blog
Stack Overflow Blog
Stack Overflow Blog
V
Vulnerabilities – Threatpost
H
Help Net Security
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Last Week in AI
Last Week in AI
博客园 - 叶小钗

博客园 - Grandyang

[LeetCode] 1372. Longest ZigZag Path in a Binary Tree 二叉树中的最长交错路径 [LeetCode] 1371. Find the Longest Substring Containing Vowels in Even Counts 每个元音包含偶数次的最长子字符串 [LeetCode] 1370. Increasing Decreasing String 上升下降字符串 [LeetCode] 1368. Minimum Cost to Make at Least One Valid Path in a Grid 使网格图至少有一条有效路径的最小代价 [LeetCode] 1367. Linked List in Binary Tree 二叉树中的链表 [LeetCode] 1366. Rank Teams by Votes 通过投票对团队排名 [LeetCode] 1365. How Many Numbers Are Smaller Than the Current Number 有多少小于当前数字的数字 [LeetCode] 1362. Closest Divisors 最接近的因数 [LeetCode] 1361. Validate Binary Tree Nodes 验证二叉树 [LeetCode] 1360. Number of Days Between Two Dates 日期之间隔几天 [LeetCode] 1359. Count All Valid Pickup and Delivery Options 有效的快递序列数目 [LeetCode] 1358. Number of Substrings Containing All Three Characters 包含所有三种字符的子字符串数目 [LeetCode] 1357. Apply Discount Every n Orders 每隔n个顾客打折 [LeetCode] 1356. Sort Integers by The Number of 1 Bits 根据数字二进制下1 的数目排序 [LeetCode] 1354. Construct Target Array With Multiple Sums 多次求和构造目标数组 [LeetCode] 1353. Maximum Number of Events That Can Be Attended 最多可以参加的会议数目 [LeetCode] 1352. Product of the Last K Numbers 最后 K 个数的乘积 [LeetCode] 1351. Count Negative Numbers in a Sorted Matrix 统计有序矩阵中的负数 [LeetCode] 1349. Maximum Students Taking Exam 参加考试的最大学生数
[LeetCode] 1363. Largest Multiple of Three 形成三的最大倍数
Grandyang · 2024-01-11 · via 博客园 - Grandyang

Given an array of digits digits, return the largest multiple of three that can be formed by concatenating some of the given digits in any order. If there is no answer return an empty string.

Since the answer may not fit in an integer data type, return the answer as a string. Note that the returning answer must not contain unnecessary leading zeros.

Example 1:

Input: digits = [8,1,9]
Output: "981"

Example 2:

Input: digits = [8,6,7,1,0]
Output: "8760"

Example 3:

Input: digits = [1]
Output: ""

Constraints:

  • 1 <= digits.length <= 10^4
  • 0 <= digits[i] <= 9

这道题说是给了一个只含有数字0到9的数组 digits,现在说是可以在数组取出任意的数字,需要拼成一个3的倍数,返回可以拼出的最大的数字。根据题目中的例子不难理解题意,当然这里我们不能用暴力搜索的方法,比如找出所有的子集,然后判断是否能整除3,这种方法太不高效了,因为数字的个数最多有一万个,子集的个数太多了,不能一一验证。那么只能另辟蹊径,即然是要拼成3的倍数,在小学就应该学过能被3整除的数字的特性,就是每一位上的数字加起来也能被3整除,可以利用这个性质来做。

这里将数组中的每个数字都加起来,判断得到的数字之和对3取余,若能整除,说明每个数字都可以使用上,返回数字中就把大的放到前面就可以了。难点就在于如何处理不能整除的情况,这里的余数只有两种情况,1和2。若余数为1的话,最理想的情况就是直接去除掉一个1,但原数组中不一定有1,或者去掉一个4,或者7,都可以让余数为0。假如 1,4,7 这三个数字都不存在,那么只能考虑去除两个数字,比如2和2,2和5,或者5和8等等。同理,若余数为2的话,最理想的情况就是直接去除掉一个2,但原数组中不一定有2,或者去掉一个5,或者8,都可以让余数为0。假如 2,5,8 这三个数字都不存在,那么只能考虑去除两个数字,比如1和1,1和4,或者4和7等等。

分析到这里,应该就变得容易多了,新建两个数组 rem1 和 rem2,其中 rem1 中按顺序放入 1,4,7,2,5,8,rem2 中按顺序放入 2,5,8,1,4,7。为了快速知道某个数字是否存在,统计 digits 数组中每个数字出现的个数,可以用一个长度为 10 的数组 cnt 来统计0到9每个数字出现的次数,在统计的过程中同时计算出数组和 sum。接下来进行 while 循环,条件是 sum 对3取余不为0,然后用一个 for 循环遍历,按顺序从 rem1 或者 rem2 中取数验证,判断若 sum 对3取余的余数是1,并且此时的 rem1[i] 数字存在的话,则用 sum 减去 rem1[i],并且对应的在 cnt 中的计数自减1,这样的话就可以按顺序去尽可能的移除较小的数,从而使得余数变为0。同理,若 sum 对3取余的余数是2,并且此时的 rem2[i] 数字存在的话,则用 sum 减去 rem2[i],并且对应的在 cnt 中的计数自减1,参见代码如下:


class Solution {
public:
    string largestMultipleOfThree(vector<int>& digits) {
        string res;
        vector<int> rem1{1, 4, 7, 2, 5, 8}, rem2{2, 5, 8, 1, 4, 7}, cnt(10);
        int sum = 0;
        for (int digit : digits) {
            ++cnt[digit];
            sum += digit;
        }
        while (sum % 3 != 0) {
            for (int i = 0; i < 6; ++i) {
                if (sum % 3 == 1 && cnt[rem1[i]]) {
                    sum -= rem1[i];
                    --cnt[rem1[i]];
                    break;
                } else if (sum % 3 == 2 && cnt[rem2[i]]) {
                    sum -= rem2[i];
                    --cnt[rem2[i]];
                }
            }
        }
        for (int i = 9; i >= 0; --i) {
            res += string(cnt[i], '0' + i);
        }
        return res.size() && res[0] == '0' ? "0" : res;
    }
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/1363

参考资料:

https://leetcode.com/problems/largest-multiple-of-three/

https://leetcode.com/problems/largest-multiple-of-three/solutions/532860/simple-solution-with-brief-explanation-time-o-n-space-o-10-constant/

LeetCode All in One 题目讲解汇总(持续更新中...)