数组与贪心算法——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,一经查实,立即删除!

相关文章

python科学计算:NumPy 简介与安装

1 NumPy 是什么&#xff1f; NumPy&#xff08;Numerical Python 的简称&#xff09;是 Python 语言中最为广泛使用的科学计算库。它支持多维数组和矩阵运算&#xff0c;并提供丰富的数学函数库&#xff0c;使得数据处理和数值计算变得更加高效。 NumPy 的核心是提供了一个强…

golang zap日志模块封装sentry

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

MFC读取PC6408板卡输入信号实例

本程序基于前期我的博客文章《MFC用信号灯模拟工控机数字量输入信号实时采集实例&#xff08;源码下载》 1、在TheradDlg.h中相关代码 ... private:unsigned short nAddr; ... TheradDlg.cpp中相关代码 #include "pc60002k.h"BOOL CTheradDlg::OnInitDialog() { ..…

Mapmost让你实现地图标注自由

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

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

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

DataWorks数据质量监控方案

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

多线程——线程安全

线程安全问题 同时满足以下两个条件时&#xff1a; 多个线程在操作共享的数据。操作共享数据的线程代码有多条。 当一个线程在执行操作共享数据的多条代码过程中&#xff0c;其他线程参与了运算&#xff0c;就会导致线程安全问题的产生。 解决这样的问题就是线程同步的方式来…

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

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

判断两个yaw角度之差是否超过了90度

一. 判断两个yaw角度之差是否超过了90度 要判断两个 yaw 角度之差是否超过 90 度&#xff0c;你可以通过计算这两个角度的差值&#xff0c;并将其归一化为 [-180, 180] 的范围内。接着&#xff0c;只需判断该差值的绝对值是否大于 90 度。 实现步骤&#xff1a; 计算角度差&…

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

近日又有一个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…

Python股票接口实现量化交易的优势是什么

炒股自动化&#xff1a;申请官方API接口&#xff0c;散户也可以 python炒股自动化&#xff08;0&#xff09;&#xff0c;申请券商API接口 python炒股自动化&#xff08;1&#xff09;&#xff0c;量化交易接口区别 Python炒股自动化&#xff08;2&#xff09;&#xff1a;获取…

MSP430F149实现1.8寸TFT_LCD真彩屏显示

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

CSRF,SSRF和重放攻击的区别

CSRF是跨站请求伪造攻击&#xff0c;由客户端发起 SSRF是服务器端请求伪造&#xff0c;由服务器发起 重放攻击时将截获的数据包进行重放&#xff0c;达到身份认证等目的 三种是不同的网络安全攻击方式&#xff0c;他们在攻击方式&#xff0c;目标&#xff0c;影响以及防御策略…

微服务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…

【软件设计】常用设计模式--策略模式

软件设计模式&#xff08;三&#xff09; 策略模式&#xff08;Strategy Pattern&#xff09;1. 概念2. 模式结构3. UML 类图4. 实现方式C# 示例步骤1&#xff1a;定义策略接口步骤2&#xff1a;实现具体策略类步骤3&#xff1a;实现上下文类步骤4&#xff1a;使用策略模式 Jav…

.NET/C#⾯试题汇总系列:基础语法

1. 字符串中string strnull和string str""和string strstring.Empty的区别&#xff1f; string str null;&#xff1a;这种方式声明了一个字符串变量str&#xff0c;并将其初始化为null。这意味着str不指向任何实际的字符串对象。如果你试图访问str的属性或方法&…