1.题目链接:
给你一个整数数组nums ,请你找出并返回能被三整除的元素最大和。
示例 1:
输入:nums = [3,6,5,1,8]
输出:18
解释:选出数字 3, 6, 1 和 8,它们的和是 18(可被 3 整除的最大和)。示例 2:
输入:nums = [4]
输出:0
解释:4 不能被 3 整除,所以无法选出数字,返回 0。
示例 3:
输入:nums = [1,2,3,4,4]
输出:12
解释:选出数字 1, 3, 4 以及 4,它们的和是 12(可被 3 整除的最大和)。
提示:
| ◦ | 1 <= nums.length <= 4 * 10^4 | |
| ◦ |
| |
3. 解法(正难则反 + 贪心 + 分类讨论):
正难则反:
我们可以先把所有的数累加在一起,然后根据累加和的结果,贪心的删除一些数。
分类讨论:
设累加和为 sum ,用 x 标记 %3 == 1 的数,用 y 标记 % 3 == 2 的数。
那么根据 sum 的余数,可以分为下面三种情况:
| a. | sum % 3 == 0 ,此时所有元素的和就是满足要求的,那么我们一个也不用删除;sum % 3 == 1 ,此时数组中要么存在一个 x ,要么存在两个 y 。因为我们要的是最大 |
| b. | |
值,所以应该选择 x 中最小的那么数,记为 x1 ,或者是 y 中最小以及次小的两个数,记
为 y1, y2 。
那么,我们应该选择两种情况下的最大值:max(sum - x1, sum - y1 - y2) ;
| c. | sum % 3 == 2 ,此时数组中要么存在一个 y ,要么存在两个 x 。因为我们要的是最大 |
值,所以应该选择 y 中最小的那么数,记为 y1 ,或者是 x 中最小以及次小的两个数,记
为 x1, x2 。
那么,我们应该选择两种情况下的最大值:max(sum - y1, sum - x1 - x2) ;
Java算法代码:
class Solution {
public int maxSumDivThree(int[] nums) {
int INF = 0x3f3f3f3f;
int sum = 0, x1 = INF, x2 = INF, y1 = INF, y2 = INF;
for(int x : nums){
sum += x;
if(x % 3 ==1){
if(x < x1){
x2 = x1;
x1 = x;
}else if(x < x2){
x2 = x;
}
}else if(x % 3 ==2){
if(x < y1){
y2 = y1;
y1 = x;
}else if(x < y2){
y2 =x;
}
}
}
//分类讨论
if(sum % 3 == 0) return sum;
else if (sum %3 ==1) return Math.max(sum - x1, sum - y1 - y2);
else return Math.max(sum - y1,sum - x1 -x2);
}
}
运行结果:

贪心策略:
要想直接想到,得思考很久的。

1098



被折叠的 条评论
为什么被折叠?



