[LeetCode] 1262. Greatest Sum Divisible by Three
Given an integer array nums
, return the maximum possible sum of elements of the array such that it is divisible by three.
Example 1:
Input: nums = [3,6,5,1,8] Output: 18 Explanation: Pick numbers 3, 6, 1 and 8 their sum is 18 (maximum sum divisible by 3).
Example 2:
Input: nums = [4] Output: 0 Explanation: Since 4 is not divisible by 3, do not pick any number.
Example 3:
Input: nums = [1,2,3,4,4] Output: 12 Explanation: Pick numbers 1, 3, 4 and 4 their sum is 12 (maximum sum divisible by 3).
Constraints:
1 <= nums.length <= 4 * 104
1 <= nums[i] <= 104
可被三整除的最大和。
给你一个整数数组 nums
,请你找出并返回能被三整除的元素最大和。
这道题的最优解是用 DP 做但是我没有很理解,这里我给出一个次优解,思路是贪心。
既然是找最大的和,那么首先我们可以看一下把整个数组都加起来的和 sum 是否能 % 3,如果 sum % 3 == 0,那么就无须减去任何元素。
比较一般的 case 是 sum % 3 != 0,我们可以创建两个数组 a 和 b,一个放 % 3 == 1 的所有元素,另一个放 % 3 == 2 的所有元素。
- 如果 sum % 3 == 1,需要减去的是数组 a 里面最小的数字(这个数字 % 3 == 1);或者如果数组 b 里面超过两个元素,我们减去 b 里最小的两个元素(这两个元素的和 % 3 == 1)。这两种情况取较小值
- 如果 sum % 3 == 2,如果 b 不为空,直接减去 b 中最小数字(这个数字 % 3 == 2);或者 a 中也有至少两个数字,那么减去 a 里最小的两个元素(这两个元素的和 % 3 == 2)。这两种情况取较小值
时间O(n)
空间O(n)
Java实现
1 class Solution { 2 public int maxSumDivThree(int[] nums) { 3 int sum = 0; 4 for (int num : nums) { 5 sum += num; 6 } 7 // corner case 8 if (sum % 3 == 0) { 9 return sum; 10 } 11 12 // normal case 13 List<Integer> a = new ArrayList<>(); 14 List<Integer> b = new ArrayList<>(); 15 for (int num : nums) { 16 if (num % 3 == 1) { 17 a.add(num); 18 } else if (num % 3 == 2) { 19 b.add(num); 20 } 21 } 22 Collections.sort(a); 23 Collections.sort(b); 24 25 if (sum % 3 == 2) { 26 List<Integer> temp = a; 27 a = b; 28 b = temp; 29 } 30 int res = a.isEmpty() ? 0 : sum - a.get(0); 31 if (b.size() > 1) { 32 res = Math.max(res, sum - b.get(0) - b.get(1)); 33 } 34 return res; 35 } 36 }