尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

详细介绍:LeetCode 每日一题笔记 日期:2025.11.23 题目:1262.可被三整除的最大和

详细介绍:LeetCode 每日一题笔记 日期:2025.11.23 题目:1262.可被三整除的最大和
📅 发布时间:2026/6/22 2:27:13

LeetCode 每日一题笔记

0. 前言

  • 日期:2025.11.23
  • 题目:1262.可被三整除的最大和
  • 难度:中等
  • 标签:数组 贪心 动态规划

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 整除的最大和)。

关键分析:

  • 目标是找到子数组(或子集)和的最大值,且该和能被 3 整除;
  • 若数组所有元素和本身能被 3 整除,直接返回该和;
  • 若和不能被 3 整除,需通过移除最小的“代价”(即最小的元素或元素组合),使剩余和能被 3 整除,且保证剩余和最大。

2. 解题思路

核心观察

  1. 数组所有元素的总和 max 是“潜在最大和”,若 max % 3 == 0,直接返回 max;
  2. 若 max % 3 == 1:需移除以下两种情况中“代价最小”的一种(保证剩余和最大):
    • 移除 1 个“模 3 余 1”的最小元素;
    • 移除 2 个“模 3 余 2”的最小元素(缘于 2+2=4 ≡1 mod3,移除后总和模3为0);
  3. 若 max % 3 == 2:需移除以下两种情况中“代价最小”的一种:
    • 移除 1 个“模 3 余 2”的最小元素;
    • 移除 2 个“模 3 余 1”的最小元素(因为 1+1=2 ≡2 mod3,移除后总和模3为0);
  4. 提前对数组排序,确保收集到的“模 3 余 1”和“模 3 余 2”的元素是从小到大排列的,方便取最小代价。

算法步骤

  1. 对数组排序(从小到大),便于后续获取“模 3 余 1”和“模 3 余 2”的最小元素;
  2. 初始化两个数组 m1 和 m2,分别存储“模 3 余 1”和“模 3 余 2”的元素,初始值设为 Integer.MAX_VALUE(表示未填充);
  3. 遍历数组,计算所有元素的总和 max,同时将“模 3 余 1”的元素存入 m1,“模 3 余 2”的元素存入 m2;
  4. 根据 max % 3 的结果,计算需要移除的最小代价,得到最终能被 3 整除的最大和;
  5. 特殊情况:若移除后无元素剩余(如数组只有一个元素且不能被 3 整除),返回 0。

3. 代码实现

import java.util.Arrays;
class Solution {
public int maxSumDivThree(int[] nums) {
Arrays.sort(nums); // 对数组排序,方便后续获取最小的余1、余2元素
int max = 0; // 存储数组所有元素的总和(潜在最大和)
int m1[] = new int[nums.length]; // 存储模3余1的元素,初始为最大值(未填充状态)
int m2[] = new int[nums.length]; // 存储模3余2的元素,初始为最大值(未填充状态)
// 初始化m1和m2数组,所有元素设为Integer.MAX_VALUE(表示未使用的位置)
for(int i = 0; i < m1.length; i++){
m1[i] = m2[i] = Integer.MAX_VALUE;
}
int pos1 = 0; // m1数组的填充指针(记录当前存储到第几个余1元素)
int pos2 = 0; // m2数组的填充指针(记录当前存储到第几个余2元素)
// 遍历数组,计算总和并分类存储余1、余2的元素
for(int i : nums){
max += i; // 累加总和
if(i % 3 == 1){
m1[pos1] = i; // 存入余1元素
pos1++; // 指针后移
}
if(i % 3 == 2){
m2[pos2] = i; // 存入余2元素
pos2++; // 指针后移
}
}
// 情况1:总和模3余2,需移除最小代价使总和模3为0
if(max % 3 == 2){
// 可选方案:移除2个最小的余1元素(若存在),且代价小于移除1个最小的余2元素
if(pos1 > 1 && m1[0] + m1[1] < m2[0]){
return max - m1[0] - m1[1]; // 移除两个余1最小元素
}
// 否则:移除1个最小的余2元素(需确保存在余2元素)
return (pos2 > 0) ? max - m2[0] : 0;
}
// 情况2:总和模3余1,需移除最小代价使总和模3为0
else if(max % 3 == 1){
// 可选方案:移除2个最小的余2元素(若存在),且代价小于移除1个最小的余1元素
if(pos2 > 1 && m2[0] + m2[1] < m1[0]){
return max - m2[0] - m2[1]; // 移除两个余2最小元素
}
// 否则:移除1个最小的余1元素(需确保存在余1元素)
return (pos1 > 0) ? max - m1[0] : 0;
}
// 情况3:总和本身能被3整除,直接返回总和
else return max;
}
}

4. 代码优化说明

原代码潜在问题修复与优化

  1. 补充边界判断:原代码未处理“无对应元素可移除”的情况(如 max%3==2 但无余2元素且不足2个余1元素),优化后通过 pos1>0、pos2>0 判断,无对应元素时返回 0;
  2. 数组初始化优化:m1 和 m2 长度设为 nums.length 足够存储所有对应元素,初始值用 Integer.MAX_VALUE 区分“未填充位置”,避免混淆;
  3. 排序意义明确:数组排序后,m1 和 m2 中存储的元素天然从小到大排列,无需额外排序,直接取前 1 个或 2 个元素即为最小代价。

可进一步优化方向

  1. 空间优化:m1 和 m2 无需存储所有对应元素,只需记录前 2 个最小元素(因为最多需要移除 2 个),可将数组改为长度为 2 的变量,空间复杂度从 O(n) 降为 O(1);
  2. 避免冗余计算:遍历数组时可直接记录前 2 个最小的余1、余2元素,无需存储整个数组后再取前两个。

5. 复杂度分析

  • 时间复杂度:O(n log n),核心开销来自数组排序(Arrays.sort(nums)),遍历数组的时间为 O(n),整体受排序主导;
  • 空间复杂度:O(n),用于存储 m1 和 m2 数组(长度均为 n),若优化为仅存储前 2 个最小元素,可降至 O(1)。

6. 总结

解题核心

  • 贪心思想:以“数组总和”为基础,通过移除最小代价(最小元素或最小元素组合)使总和能被 3 整除,保证剩余和最大;
  • 分类讨论:根据总和模 3 的结果,针对性处理两种可能的移除方案,确保覆盖所有情况。

关键注意点

  • 边界处理:当无对应元素可移除时(如数组只有一个元素且不能被 3 整除),需返回 0;
  • 最小代价判断:当有两种移除方案时,需选择“移除元素和更小”的方案,确保剩余和最大。

适用场景

  • 该思路适用于“求能被 k 整除的最大和”类问题,核心是借助分类存储余数元素,针对性移除最小代价。

对比动态规划思路

  • 贪心思路(本题建立):空间开销可优化至 O(1),时间复杂度受排序影响为 O(n log n),逻辑直观易理解;
  • 动态规划思路:时间复杂度 O(n),空间复杂度 O(1),无需排序,适合对时间效率要求更高的场景。
    两种思路均可解决问题,可根据个人理解和场景选择。

相关新闻

  • Excalidraw依赖注入模式:提升代码可测试性
  • 18、C、脚本语言与WSH对象的深入解析
  • 轨迹记录软件哪个好?看是否支持多终端查看 - 企业数字化观察家

最新新闻

  • CI/CD 流水线自动化与 GitOps 实践:让部署从手工活变成流水线
  • AudioLLM语音翻译技术解析:架构、评估与实战对比
  • 3分钟快速上手:免费高效的Mem Reduct内存监控工具终极指南
  • 量子纠错码优化:线性规划与半正定规划的应用
  • 半导体设备年会优选指南,盘点业内大咖精选半导体设备展会 - 品牌深度评测
  • Ubuntu 20.04下MongoDB远程访问三重安全配置指南

日新闻

  • 2026速览惠州叛逆青少年学校前十大排名名单出炉 - 武汉中职最新信息发布
  • 2026上饶白蚁消杀哪家好?15年本土2大权威白蚁防治公司推荐(金盾虫控/青蚁卫士) - 我叫一
  • 天龙八部单机版终极数据管理工具:5个技巧快速掌握游戏数据编辑

周新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号