作者:小迅
链接:https://leetcode.cn/problems/greatest-sum-divisible-by-three/solutions/2314049/tan-xin-zhu-shi-chao-ji-xiang-xi-by-xun-r0n76/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
题目
思路
题意 -> 给你一个整数数组 nums,请你找出并返回能被三整除的元素最大和。
由于数组中没有负数,如果整个数组的元素和 s 可以被 3 整除,那么 s 就是最大的元素和。
否则,如果 s 不能被 3 整除,那就看看能否让 s 减去某些 nums[i],使得 s 可以被 3 整除。
找到所有 nums[i] mod 3=1 的 nums[i],放到数组 a1 中;找到所有 nums[i] mod 3=2 的 nums[i],放到数组 a2中。对 a1和 a2 从小到大排序。分类讨论:
- 如果 s mod 3=1:
- 如果 a1 不为空,那么答案可能是 s−a1[0];
- 如果 a2 中至少有两个数,那么答案可能是 s−a2[0]−a2[1];
- 这两种情况取最大值。
- 如果没有这样的数,返回 0。
- 如果 s mod 3=2:
- 如果 a2 不为空,那么答案可能是 s−a2[0];
- 如果 a1 中至少有两个数,那么答案可能是 s−a1[0]−a1[1];
- 这两种情况取最大值。
- 如果没有这样的数,返回 0。
代码实现时,如果 s mod 3=2,那么可以交换数组 a1 和 a2,从而复用同一套逻辑。
代码注释超级详细
代码
static int cmp(const void *a, const void *b) {//升序
return *(int *)a - *(int *)b;
}
int maxSumDivThree(int* nums, int numsSize) {
int a[3][numsSize];
memset(a, 0, sizeof(a));
int i = 0, j = 0, sum = 0;//初始化
for (int m = 0; m < numsSize; ++m) {//枚举所有元素
sum += nums[m];//统计元素和
if (nums[m] % 3 == 1) {//保存当前元素的余数
a[nums[m] % 3][i++] = nums[m];
} else if (nums[m] % 3 == 2) {
a[nums[m] % 3][j++] = nums[m];
}
}
if (sum % 3 == 0) return sum;//正好完成整除
qsort(a[1], i, sizeof(a[1][0]), cmp);
qsort(a[2], j, sizeof(a[2][0]), cmp);//升序
int *a1 = a[1], *a2 = a[2];//指针交换位置非常方便
if (sum % 3 == 2) {//情况二,交换指针
a1 = a[2];
a2 = a[1];
int temp = i;
i = j;
j = temp;
}
int ans = i == 0 ? 0 : sum - a1[0];//情况一判断
if (j > 1) ans = fmax(ans, sum - a2[0] - a2[1]);//情况二判断
return ans;
}
作者:小迅
链接:https://leetcode.cn/problems/greatest-sum-divisible-by-three/solutions/2314049/tan-xin-zhu-shi-chao-ji-xiang-xi-by-xun-r0n76/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。