每日一题力扣 1262 https://leetcode.cn/problems/greatest-sum-divisible-by-three/
、
题解
这道题目核心就算是要知道如果x%3=2的话,应该要去拿%3=1的数字,这样子才能满足%3=0
贪心
sum不够%3的时候,就减去余数为1的或者余数为2的 需要注意 两个余数为1会变成余数为2的,所以可能减去2个余数为1
核心代码如下
public int maxSumDivThreeOther(int[] nums) {
int sum = Arrays.stream(nums).sum();
if (sum%3==0){
return sum;
}
// 要么减去1的 要么减去2的
ArrayList<Integer> a1 = new ArrayList<>();
ArrayList<Integer> a2 = new ArrayList<>();
for (int i = 0; i < nums.length; i++) {
if (nums[i]%3==1){
a1.add(nums[i]);
}
if (nums[i]%3==2){
a2.add(nums[i]);
}
}
Collections.sort(a1);
Collections.sort(a2);
// 判断减去哪个
int max=0;
if (sum%3==1&&!a1.isEmpty()){
max=Math.max(max,sum-a1.get(0));
}
if (sum%3==1&&a2.size()>=2){
max=Math.max(max,sum-a2.get(0)-a2.get(1));
}
if (sum%3==2&&!a2.isEmpty()){
max=Math.max(max,sum-a2.get(0));
}
if (sum%3==2&&a1.size()>=2){
max=Math.max(max,sum-a1.get(0)-a1.get(1));
}
return max;
}
dp
不需要知道前面几个选了什么
1.dp
然后在前面几个0,i-1选择数值为s的,然后(s+x)%3 =j 算出s=(j-x)%3 这样子,不过如果出现负号的话,还是需要先+3的
如下代码
public int maxSumDivThreeOther2(int[] nums) {
int n=nums.length;
//1.dp[i][j] 表示0-i 选了若干个,余数总共是j的 最大数值
int[][] dp = new int[n+1][3];
// 2.递推式 是要求从前i-1个 拿数值s ,要求j的位置上 (s+x)%3==j 所以s=(j-x)%3 由于(j-x)%3 可能是符号 -2 -1 这种 所以要+3
dp[0][0]=0;
//非法数字 0个数字余数是1 为了避免选择这个 就后续可以让0和Integer.MIN_VALUE比较
dp[0][1]=Integer.MIN_VALUE;
dp[0][2]=Integer.MIN_VALUE;
for (int i = 1; i <= n; i++) {
for (int j = 0; j < 3; j++) {
int pre=(j-nums[i-1])%3;
if ((j-nums[i-1]) %3<0){
pre+=3;
}
dp[i][j]=Math.max(dp[i-1][j],dp[i-1][pre ]+nums[i-1]);
}
}
return dp[n][0];
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人