当前位置: 首页 > news >正文

【贪心算法】(第十四篇)

目录

可被三整除的最⼤和(medium)

题目解析

讲解算法原理

编写代码

距离相等的条形码(medium)

题目解析

讲解算法原理

编写代码


可被三整除的最⼤和(medium)

题目解析

1.题目链接:. - 力扣(LeetCode)

2.题目描述

给你⼀个整数数组 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
◦ 1 <= nums[i] <= 10^4

讲解算法原理

解法(正难则反+贪⼼+分类讨论):
正难则反:

我们可以先把所有的数累加在⼀起,然后根据累加和的结果,贪⼼的删除⼀些数。
分类讨论:
设累加和为 sum ,⽤ x 标记 %3 == 1 的数,⽤ y 标记 % 3 == 2 的数。那么根据 sum 的余数,可以分为下⾯三种情况:
a. sum % 3 == 0 ,此时所有元素的和就是满⾜要求的,那么我们⼀个也不⽤删除;b. sum % 3 == 1 ,此时数组中要么存在⼀个 x ,要么存在两个 y 。因为我们要的是最⼤
值,所以应该选择 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) ;

编写代码

c++算法代码:

class Solution
{
public:int maxSumDivThree(vector<int>& nums) {const int INF = 0x3f3f3f3f;int sum = 0, x1 = INF, x2 = INF, y1 = INF, y2 = INF;for(auto 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 max(sum - x1, sum - y1 - y2);else return 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);}
}

距离相等的条形码(medium)

题目解析

1.题目链接:. - 力扣(LeetCode)

2.题目描述

在⼀个仓库⾥,有⼀排条形码,其中第 i 个条形码为 barcodes[i] 。
请你重新排列这些条形码,使其中任意两个相邻的条形码不能相等。你可以返回任何满⾜该要求的答案,此题保证存在答案。
⽰例1:
输⼊:barcodes=[1,1,1,2,2,2]
输出:[2,1,2,1,2,1]
⽰例2:
输⼊:barcodes=[1,1,1,1,2,2,3,3]
输出:[1,3,1,3,2,1,2,1]
提⽰:
◦ 1 <= barcodes.length <= 10000
◦ 1 <= barcodes[i] <= 10000

讲解算法原理

解法(贪⼼):
贪⼼策略:

每次处理⼀批相同的数字,往n个空⾥⾯摆放;
每次摆放的时候,隔⼀个格⼦摆放⼀个数;
优先处理出现次数最多的那个数。

编写代码

c++算法代码:

class Solution
{
public:vector<int> rearrangeBarcodes(vector<int>& b) {unordered_map<int, int> hash; // 统计每个数出现的频次 int maxVal = 0, maxCount = 0; for(auto x : b){if(maxCount < ++hash[x]){maxCount = hash[x];maxVal = x;}}int n = b.size();vector<int> ret(n);int index = 0;// 先处理出现次数最多的那个数for(int i = 0; i < maxCount; i++){ret[index] = maxVal;index += 2;}// 处理剩下的数hash.erase(maxVal);for(auto& [x, y] : hash){for(int i = 0; i < y; i++){if(index >= n) index = 1;ret[index] = x;index += 2;}}return ret;}
};

java算法代码:

class Solution
{public int[] rearrangeBarcodes(int[] b) {Map<Integer, Integer> hash = new HashMap<>(); // 统计每个数出现了多少次 int maxVal = 0, maxCount = 0;for(int x : b){hash.put(x, hash.getOrDefault(x, 0) + 1);if(maxCount < hash.get(x)){maxVal = x;maxCount = hash.get(x);}}int n = b.length;int[] ret = new int[n];int index = 0;// 先处理出现次数最多的那个数for(int i = 0; i < maxCount; i++){ret[index] = maxVal;index += 2;}hash.remove(maxVal);for(int x : hash.keySet()){for(int i = 0; i < hash.get(x); i++){if(index >= n) index = 1;ret[index] = x;index += 2;}}return ret;}
}


http://www.mrgr.cn/news/58274.html

相关文章:

  • 什么情况?特斯拉暴涨超20%!
  • 探索人工智能在自然语言处理中的应用
  • 【嵌入式】MQTT详解
  • Spring源码解析(35)之Spring全体系源码流程图
  • 【开源免费】基于SpringBoot+Vue.JS蜗牛兼职平台 (JAVA毕业设计)
  • Django配置路由后,为什么输入http://127.0.0.1:8000/ 网址后报错了?
  • 落实安全左移迫在眉睫 | 伊朗APT34组织针对阿联酋及海湾关键基础设施发动攻击
  • uniapp:sqlite最详细教程,小白可直接粘贴复制
  • Linux 学习笔记(十七)—— 文件系统
  • MultipartFile文件与传递body并存问题
  • RK3568 android11 usb接口TP与电磁笔触点上报优先级问题
  • 【运维心得】U盘启动安装Dell服务器踩坑指南
  • 【JavaScript】JavaScript 进阶-2-构造函数数据常用函数(更新中)
  • Python:背景知识及环境安装
  • Linux内核常见的网络丢包场景分析,零基础入门到精通,收藏这一篇就够了
  • 强推!清华大佬强力打造,绝对是2024年人工智能入门天花板教程!
  • 智慧农业大数据平台:智汇田园,数驭未来
  • 220V降12V0.5A500mA恒压WT5105
  • 【话题】创智时代:人工智能重塑生活与工作
  • 空间转录组 | ​Stereo-seq在疾病中的应用研究
  • C++ 设计模式 - 每日持续更新中
  • httpd服务
  • 怎么区分主谓宾I love you与主系表I am fine? 去掉宾语看句子完整性 主系表结构则侧重于描述主语的状态、特征或性质
  • 移远通信亮相重庆燃气展:以多领域技术实力推动燃气发展安全化、智能化
  • (自用复习题)常微分方程07
  • 如此酷的锁屏时钟屏保 怎么能不告诉你