数组与贪心算法——605、121、122、561、455、575(5简1中)

605. 种花问题(简单)

假设有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花不能种植在相邻的地块上,它们会争夺水源,两者都会死去。

给你一个整数数组 flowerbed 表示花坛,由若干 0 和 1 组成,其中 0 表示没种植花,1 表示种植了花。另有一个数 n ,能否在不打破种植规则的情况下种入 n 朵花?能则返回 true ,不能则返回 false 。

 解法一、贪心

先种满,数数满了多出来几朵,再讨论n在不在范围内。对边界要求有点高。。

题解里较完美的一个if条件:

 if ((i == 0 || f[i - 1] == 0) && f[i] == 0 && (i == m - 1 || f[i + 1] == 0))

class Solution {public boolean canPlaceFlowers(int[] flowerbed, int n) {int num = flowerbed.length;int res = 0;if(num == 1){return n==0 || flowerbed[0] == 0 && n == 1 ;}else if(num == 2){return n==0 || ((flowerbed[0] == 0 && flowerbed[1] == 0) && n == 1);}for(int i = 0; i < num;i++){if(i == 0 && flowerbed[0] == 0 && flowerbed[1] == 0){flowerbed[0] = 1;res++;}else if(i == num-1 && flowerbed[i-1] == 0 && flowerbed[i] == 0){res++;}else if(i > 0 && i < num - 1 && flowerbed[i] != 1 && flowerbed[i+1] != 1 && flowerbed[i-1] != 1){flowerbed[i] = 1;res++;}}return n <= res;}
}

121. 买卖股票的最佳时机(简单)

给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。

你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。

返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。 

解法一、暴力(超时)

一开始确实想不动脑子来着(

public class Solution {public int maxProfit(int[] prices) {int maxprofit = 0;for (int i = 0; i < prices.length - 1; i++) {for (int j = i + 1; j < prices.length; j++) {int profit = prices[j] - prices[i];if (profit > maxprofit) {maxprofit = profit;}}}return maxprofit;}
}

解法二、类dp

但不需要维护一个dp数组,只需要维护一个从0-k(0<=k<n)的最小买入值就好

class Solution {public int maxProfit(int[] prices) {int min = prices[0];int profit = 0;for(int i = 1;i < prices.length;i++){profit = Math.max(prices[i] - min,profit);min = Math.min(min,prices[i]);}return profit;}
}

122. 买卖股票的最佳时机 II(中等)

给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。

在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。

返回 你能获得的 最大 利润 。

解法一、贪心

本质思想就是一旦有钱赚马上买入卖出。注意:贪心只能模拟思想过程,不是实际交易过程。如对于[1,3,4],贪心是1买3卖、3买4卖,交易过程是1买4卖。两者利益等价,行为不等价。

本题还有很多其他类型,尤其是dp/递增栈,但果然还是放在dp专题里做比较好吧~这方面就不贪心了!

class Solution {public int maxProfit(int[] prices) {int profit = 0;if(prices.length < 2)return 0;for(int i = 1;i < prices.length;i++){if(prices[i] > prices[i-1])profit += prices[i] - prices[i-1];}return profit;}
}

561. 数组拆分(简单) 

给定长度为 2n 的整数数组 nums ,你的任务是将这些数分成 n 对, 例如 (a1, b1), (a2, b2), ..., (an, bn) ,使得从 1 到 n的 min(ai, bi) 总和最大。

返回该 最大总和 。

解法一、排序

要取最大,也就是尽量把小的和小的堆一起,大的和大的堆一起。所以先排序,排序后数组偶数位置的和就是所求。

class Solution {public int arrayPairSum(int[] nums) {Arrays.sort(nums);int n = nums.length,sum = 0;for(int i = 0;i < n;i +=2){sum+=nums[i];}return sum;}
}

解法二、数组排序

从代码示例那边看到的。这个和之前看到的那个取maxSum、minSum然后/2的技法其实有点像,桶排序虽然麻烦但是耗时真的很低。这里直接取gpt的解释吧。

  • index 用来追踪当前已经遍历的数值的累计个数。

  • res 是用于存储最终的结果。

每当 arr[i] > 0,意味着索引 i 对应的数值在 nums 中出现过,代码会根据当前的 index 和 arr[i] 的值来计算部分结果:

  • ((index + 1) % 2 + arr[i]) / 2 这个表达式与确定中位数位置相关,它用于决定是否将该数值纳入 res的计算。

  • (i - 10000) 将索引 i 转换回原来的数值范围(因为我们之前对 nums 的数值进行了偏移处理)。

最后,index = index + arr[i] 用于更新累计的数值个数。

((index + 1) % 2 + arr[i]) / 2 这个表达式的作用是用于控制在遍历过程中,是否选择将当前 i 对应的数值 (即 i - 10000) 贡献给最终的 res 结果。让我们一步一步拆解它的含义:

1. index + 1

index 是用来记录遍历到当前位置之前,总共处理过的元素的个数。index + 1 表示当前的元素是所有已经遍历过的元素中的第几个。

2. % 2

对 index + 1 取模 2 的作用是确定当前这个元素是偶数还是奇数。它会返回两种情况:

  • 当 index + 1 是奇数时,(index + 1) % 2 = 1

  • 当 index + 1 是偶数时,(index + 1) % 2 = 0

这个结果决定了后续表达式的一个偏移调整。

3. arr[i]

arr[i] 表示当前索引 i 对应的数值在 nums 数组中出现的次数。

4. ((index + 1) % 2 + arr[i])

这一步是把 (index + 1) % 2 和 arr[i] 的值加起来:

  • 如果当前是奇数个元素 ((index + 1) % 2 = 1),那么结果就是 1 + arr[i]

  • 如果当前是偶数个元素 ((index + 1) % 2 = 0),那么结果就是 0 + arr[i]

这相当于调整了 arr[i] 的数值,使得某些条件下它多加 1 或不变,这和计算中位数的位置有关系。

5. / 2

这一步是对整个表达式进行除以 2:

  • 如果 arr[i] 是偶数或者 (index + 1) % 2 是 0,那么 (index + 1) % 2 + arr[i] 是偶数,除以 2 后返回一个整数。

  • 如果 arr[i] 是奇数,并且 (index + 1) % 2 = 1,这会使得奇数变为偶数的一半。

总体意义

这个表达式的作用在于,在遍历过程中,根据当前遍历的元素顺序(index)以及该元素的出现次数(arr[i]),判断要不要取一半的数值(除以 2),这样就可以控制贡献给 res 的数值。在处理中位数相关的算法时,这个操作可以帮助判断中位数所在位置以及应取多少值。

举例

假设:

  • arr[i] = 3 表示当前这个数出现了 3 次,

  • index + 1 = 5 表示当前是第 5 个元素,

那么:

  • (index + 1) % 2 = 1,所以 ((index + 1) % 2 + arr[i]) = 1 + 3 = 4

  • / 2 后结果是 2,表示将当前的数值贡献 2 次。

这个操作对中位数或者其他与位置相关的统计操作有帮助。

class Solution {public int arrayPairSum(int[] nums) {if (nums.length <= 1800) {Arrays.sort(nums);int sum = 0;for (int i = 0; i < nums.length; i = i + 2) {sum = sum + nums[i];}return sum;} else {// 在该用数组排序的时候又把这件事忘了个干净int[] arr = new int[20001];for (int i = 0; i < nums.length; i++) {arr[nums[i] + 10000]++;}int index = 0;int res = 0;for (int i = 0; i < arr.length; i++) {if (arr[i] > 0) {res = res + ((index + 1) % 2 + arr[i]) / 2 * (i - 10000);index = index + arr[i];}}return res;}}
}

455. 分发饼干(简单)

假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。

对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] 。如果 s[j] >= g[i],我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是满足尽可能多的孩子,并输出这个最大数值。

解法一、排序+双指针

先排序。如果饼干比当前孩子胃口值小,那么饼干值往后挑。否则,i++,j++,计入结果。

class Solution {public int findContentChildren(int[] g, int[] s) {int i = 0,j = 0,res = 0;Arrays.sort(g);Arrays.sort(s);while(i < g.length && j < s.length){while(i < g.length && j < s.length && s[j] < g[i])j++;if(i < g.length && j < s.length && s[j] >= g[i]){i++;j++;res++;}}return res;}
}

稍微改善一些(2ms)的情况。在这次的循环里,以孩子都吃到为前提条件,如果饼干用完,则结束,减少了反复判断。

 public int findContentChildren0(int[] g, int[] s) {Arrays.sort(g);Arrays.sort(s);int result = 0;int j = 0;for (int i = 0; i < g.length; i++) {while (j < s.length && g[i] > s[j]) {j++;}if (j >= s.length) {break;}j++;result++;}return result;}

575. 分糖果(简单) 

Alice 有 n 枚糖,其中第 i 枚糖的类型为 candyType[i] 。Alice 注意到她的体重正在增长,所以前去拜访了一位医生。

医生建议 Alice 要少摄入糖分,只吃掉她所有糖的 n / 2 即可(n 是一个偶数)。Alice 非常喜欢这些糖,她想要在遵循医生建议的情况下,尽可能吃到最多不同种类的糖。

给你一个长度为 n 的整数数组 candyType ,返回: Alice 在仅吃掉 n / 2 枚糖的情况下,可以吃到糖的 最多种类数

解法一、枚举

只要品种不同就过,如果达到满值就break 

class Solution {public int distributeCandies(int[] candyType) {int res = 0,n2 = candyType.length;Arrays.sort(candyType);for(int i = 0;i < n2;i++){if(res == n2/2)return n2/2;res++;while(i < n2-1 && candyType[i]==candyType[i+1])i++;}return res;}
}

解法二、数据结构去重

 本质上就是统计种类,然后返回Math.min(n/2,m)的东西,只要能够统计种类,什么方法都可以。

class Solution {public int distributeCandies(int[] candyType) {Set<Integer> set = new HashSet<Integer>();for (int candy : candyType) {set.add(candy);}return Math.min(set.size(), candyType.length / 2);}
}作者:力扣官方题解
链接:https://leetcode.cn/problems/distribute-candies/solutions/1072396/fen-tang-guo-by-leetcode-solution-l4f6/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

碎碎念

  • 605需要转换思维,121、122是一个系列,考察dp还蛮有意思的。其中122的贪心做法比其他想法都要简单。感觉贪心里目前用到排序的次数很多

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/53248.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

golang zap日志模块封装sentry

我们自己写个log日志包&#xff0c;把zap和sentry封装到一起。 下面直接贴上主要部分代码&#xff08;两个模块初始化部分的代码请自行查阅官方文档&#xff09;&#xff1a; logger.go package logimport ("github.com/getsentry/sentry-go""go.uber.org/zap…

Mapmost让你实现地图标注自由

最近在勤勤恳恳&#xff08;moyuhaushui&#xff09;搬砖之余&#xff0c;偶然间看到一个在线古籍图书馆&#xff0c;虽然对文言文阅读的心理障碍不亚于英文阅读理解&#xff0c;但网站中有很多历史图集还是引起了兴趣。比如这幅《水经注图》&#xff0c;顺藤摸瓜的瞧&#xff…

Java中对象拷贝的深度解析:从零拷贝到深拷贝的演进

前言 在Java编程世界中&#xff0c;对象的拷贝是一个基础而重要的操作。它涉及到内存管理、数据一致性以及程序的健壮性等多个方面。随着软件架构的复杂化和数据的多样化&#xff0c;对象拷贝的策略也从最初的简单赋值&#xff08;零拷贝&#xff09;发展到深拷贝&#xff0c;…

DataWorks数据质量监控方案

背景 日常的调度监控&#xff0c;可以查看实例任务的运行情况&#xff0c;对运行失败的实例进行告警&#xff0c;但是却无法对运行成功的实例进行数据质量的判断。而有些情况下&#xff0c;即使实例任务运行成功了&#xff0c;数据也仍然存在问题&#xff0c;这时候就需要对数…

揭秘Taboola原生广告:欧美流量变现联盟营销金牌策略

揭秘Taboola原生广告&#xff1a;欧美流量变现的金牌策略 在数字营销日益精进的今天&#xff0c;如何高效地将网站流量转化为实际收益成为了众多欧美网站主关注的焦点。Taboola&#xff0c;作为原生广告领域的佼佼者&#xff0c;凭借其独特的广告展示方式与强大的数据驱动能力…

上海晋名室外危化品暂存柜助力新能源行业发展

近日又有一个SAVEST室外危化品暂存柜项目成功验收交付使用。 用户在日常经营活动中涉及到气瓶和硅粉的室外安全暂存问题&#xff0c;4月下旬在网上看到上海晋名室外暂存柜系列很感兴趣&#xff0c;联系到了销售部钟经理&#xff0c;双方对晋名的室外暂存柜进行了高效的沟通&am…

无人机+应用综合实训室解决方案

随着无人机技术的飞速发展&#xff0c;其在航拍、农业、环境监测、物流运输等多个领域展现出巨大的应用潜力。为了满足职业院校及企业对无人机应用技术型人才的培养需求&#xff0c;唯众紧跟市场趋势&#xff0c;推出了全面且详尽的《无人机应用综合实训室解决方案》。本方案旨…

MACOS安装配置前端开发环境

官网下载安装Mac版本的谷歌浏览器以及VS code代码编辑器&#xff0c;还有在App Store中直接安装Xcode&#xff08;里面自带git&#xff09;&#xff1b; node.js版本管理器nvm的下载安装如下&#xff1a; 参考B站&#xff1a;https://www.bilibili.com/video/BV1M54y1N7fx/?sp…

【学习AI-相关路程-工具使用-自我学习-jetson模型训练-图片识别-使用模型检测图片-基础样例 (5)】

【学习AI-相关路程-工具使用-自我学习-jetson&模型训练-图片识别-使用模型检测图片-基础样例 &#xff08;5&#xff09;】 1 -前言2 -环境说明3 -先行了解&#xff08;1&#xff09;整理流程了解&#xff08;2&#xff09;了解模型-MobileNet1、MobileNetV2 的主要特性&am…

python源码 PBOCMaster MAC的计算函数及计算过程 2des

注意最后一步要用整个key加密 计算过程&#xff1a; MAC&#xff1a; PBOC-MAC DES算法 密钥 长度16(0x10)字节 57 75 20 4D 69 61 6F 6A 75 6E 40 47 26 44 43 11 初始向量 长度8(0x08)字节 00 00 00 00 00 00 00 00 数据 长度74(0x4A)字节 43 48 45 4E 48 41 4F 2D 50 43 7…

MSP430F149实现1.8寸TFT_LCD真彩屏显示

目录 一、功能实现 二、设备准备 三、接线表设计 四、代码实现 五、实现效果 六、代码链接 一、功能实现 实现1.8寸TFT_LCD真彩屏显示。显示数字、图片、字符串等。 二、设备准备 1.TFT_LCD真彩屏&#xff08;1.8寸&#xff09; 该真彩屏使用SPI通信。 2.MSP430F149开…

微服务CI/CD实践(五)Jenkins Docker 自动化构建部署Node服务

微服务CI/CD实践系列&#xff1a; 微服务CI/CD实践&#xff08;一&#xff09;环境准备及虚拟机创建 微服务CI/CD实践&#xff08;二&#xff09;服务器先决准备 微服务CI/CD实践&#xff08;三&#xff09;gitlab部署及nexus3部署 微服务CI/CD实践&#xff08;四&#xff09…

穿越机的应用行业!!!

1. 军事领域 侦察与目标搜索&#xff1a;穿越机能够快速穿越危险区域&#xff0c;执行侦察任务&#xff0c;实时获取战场信息&#xff0c;对敌方目标进行精确搜索和定位。其灵活性和机动性使其成为战场上的重要侦察工具。 目标摧毁&#xff1a;经过改装的穿越机可挂载火箭弹或…

华三防火墙第-安全策略02

一 安全策略的图解 安全策略是一种根据报文的属性信息对报文进行精细化转发控制的智能安全防护措施。它 融合了多维度精确报文识别、深度报文检测、安全动作执行、智能策略分析、应用风险调 优等多种安全防护功能,为网络的安全性提供全方位保障。 安全策略运行原理 安全策略对…

CSS实现文字环绕圆形展示

展示区域 代码区域 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><s…

ubuntu20.04搭建kubernetes1.28.13集群配置calico网络插件

写在前面 这里是我在搭建过程中从某站找到的教学视频,搭载的都是最新的,大家可以参考一下 搭建kubernetes集群学习视频: 视频链接。最后面会有我遇见报错信息的所有连接和解决方案,自行查看 不说废话,直接开搭 搭建集群大纲 一、三台虚拟机的初始化 二、三台虚拟机连接…

VTK平面切割

文章目录 一、vtkClipPolyData二、CapClip三、SolidClip四、vtkClipClosedSurface 本文的主要内容&#xff1a;简单介绍VTK中通过平面切割模型的相关功能。 哪些人适合阅读本文&#xff1a;有一定VTK基础的人。 一、vtkClipPolyData VTK官网描述&#xff1a; vtkClipPolyData使…

一个平台重要的规则改了!

大家好&#xff0c;我是凡人小哥。 是一个不黑、不吹、不跟风、有知识、有骨气的五好小号主。 现在是凌晨1点13分&#xff0c;就在昨天微信公众平台又又又调整了&#xff0c;可能朋友们还在想是不是又要严格了&#xff1f;这次恰恰相反&#xff0c;腾讯把注册微信公众号的门槛…

【Linux网络编程八】实现最简单Http服务器(基于Tcp套接字)

基于TCP套接字实现一个最简单的Http服务器 Ⅰ.Http请求和响应格式1.请求格式2.响应格式3.http中请求格式中细节字段4.http中响应格式中细节字段 Ⅱ.域名ip与URLⅢ.web根目录Ⅳ.Http服务器是如何工作的&#xff1f;一.获取请求二.分析请求2.1反序列化2.2解析url 三.构建响应3.1构…

RK3588开发板利用udp发送和接收数据

目录 1 send.cpp 2 receive.cpp 3 编译运行 4 测试 1 send.cpp #include <iostream> #include <string> #include <cstring> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> //…