Leetcode算法训练日记 | day31

news2024/11/19 14:27:32

专题九  贪心算法

一、分发饼干

1.题目

Leetcode:第 455 题

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

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

示例 1:

输入: g = [1,2,3], s = [1,1]
输出: 1
解释: 
你有三个孩子和两块小饼干,3个孩子的胃口值分别是:1,2,3。
虽然你有两块小饼干,由于他们的尺寸都是1,你只能让胃口值是1的孩子满足。
所以你应该输出1。

示例 2:

输入: g = [1,2], s = [1,2,3]
输出: 2
解释: 
你有两个孩子和三块小饼干,2个孩子的胃口值分别是1,2。
你拥有的饼干数量和尺寸都足以让所有孩子满足。
所以你应该输出2.

2.解题思路

使用贪心算法解决分发饼干问题。

1.先用大饼干去满足大胃口。在 findContentChildren 函数中,首先对两个数组 g 和 s 进行排序,这样可以实现贪心策略:将胃口最大的孩子与最大的饼干配对,然后继续为次胃口的孩子寻找次尺寸的饼干,依此类推。通过反向遍历孩子们的胃口程度数组 g,我们可以确保每个孩子都尽可能地被满足。index 变量用于跟踪当前考虑的饼干索引,result 变量用于记录能够满足的孩子数量。
在循环中,如果当前饼干的尺寸大于等于当前孩子的胃口,那么这个孩子就会被满足,result 增加,并且 index 减 1,表示已经用掉了一个饼干。这种方法可以确保在给定的饼干和孩子们的胃口下,最大化满足孩子的数量。

2.先用小饼干去满足小胃口,基本思路与1一致。

3.实现代码

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

// 一、分发饼干(用大饼干去满足大胃口)
class Solution1 {
public:
    // findContentChildren 函数用于找出能够满足的孩子们的数量
    int findContentChildren(vector<int>& g, vector<int>& s) { 
        sort(g.begin(), g.end());// 对孩子们的胃口程度数组进行升序排序
        sort(s.begin(), s.end());// 对饼干的尺寸数组进行升序排序
        int index = s.size() - 1;// 初始化 index 为饼干数组的最后一个索引
        int result = 0;// 初始化结果变量 result,用于记录满足的孩子数量
        // 从孩子们的胃口程度数组的最后一个开始向前遍历
        for (int i = g.size() - 1; i >= 0; i--) {
            // 当饼干数组的索引 index 未越界,并且当前饼干的尺寸大于等于当前孩子的胃口时
            if (index >= 0 && s[index] >= g[i]) {
                result++;// 一个孩子满足,增加结果计数
                index--;// 移动 index 到下一个饼干
            }
        }
        return result;// 返回能够满足的孩子们的数量
    }
};

// 二、分发饼干(用小饼干去满足小胃口)
class Solution2 {
public:
    // findContentChildren 函数用于找出能够满足的孩子们的数量
    int findContentChildren(vector<int>& g, vector<int>& s) {
        sort(g.begin(), g.end()); // 对孩子们的胃口大小数组进行升序排序
        sort(s.begin(), s.end());// 对饼干的大小数组进行升序排序
        int index = 0;// 初始化 index 为 0,用于记录当前满足的孩子的索引
        // 遍历所有饼干
        for (int i = 0; i < s.size(); i++) {
            // 检查是否存在一个孩子的胃口小于等于当前饼干的大小
            // 如果 index 小于 g 的大小,并且 g[index] 小于等于 s[i],则说明当前饼干可以满足一个孩子
            if (index < g.size() && g[index] <= s[i]) {
                index++;// 一个孩子满足,增加 index,表示下一个孩子将被考虑
            }
            // 如果当前饼干不能满足任何孩子的胃口,继续寻找下一个饼干
        }
        return index;// 返回能够满足的孩子们的数量
    }
};

//测试
int main()
{
    Solution1 p;
    vector<int> g = { 1, 2, 3 };
    vector<int> s = { 1, 1 };
    int result = p.findContentChildren(g, s);
    cout << "能够满足的孩子们的数量 :" <<result<< endl;
    cout <<endl;
    return 0;
}

 

二、摆动序列

1.题目

Leetcode:第 376 题

如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为 摆动序列 。第一个差(如果存在的话)可能是正数或负数。仅有一个元素或者含两个不等元素的序列也视作摆动序列。

  • 例如, [1, 7, 4, 9, 2, 5] 是一个 摆动序列 ,因为差值 (6, -3, 5, -7, 3) 是正负交替出现的。

  • 相反,[1, 4, 7, 2, 5] 和 [1, 7, 4, 5, 5] 不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。

子序列 可以通过从原始序列中删除一些(也可以不删除)元素来获得,剩下的元素保持其原始顺序。

给你一个整数数组 nums ,返回 nums 中作为 摆动序列 的 最长子序列的长度 。

示例 1:

输入:nums = [1,7,4,9,2,5]
输出:6
解释:整个序列均为摆动序列,各元素之间的差值为 (6, -3, 5, -7, 3) 。

示例 2:

输入:nums = [1,17,5,10,13,15,10,5,16,8]
输出:7
解释:这个序列包含几个长度为 7 摆动序列。
其中一个是 [1, 17, 10, 13, 10, 16, 8] ,各元素之间的差值为 (16, -7, 3, -3, 6, -8) 。

示例 3:

输入:nums = [1,2,3,4,5,6,7,8,9]
输出:2
2.解题思路

使用贪心算法解决摆动序列问题。

wiggleMaxLength 函数中,首先检查数组 nums 的大小,如果小于等于1,那么摆动长度就是数组的长度。然后,使用两个变量 curDiffpreDiff 分别记录当前元素与下一个元素的差以及前一次计算的差。变量 result 用于记录整个序列中摆动的个数。循环遍历数组,计算相邻元素的差 curDiff。如果当前差异 curDiff 与前一个差异 preDiff 异号,这意味着我们找到了一个摆动,因此将 result 加一,并更新 preDiff 为当前的 curDiff。这种方法可以有效地计算出给定数组中摆动的最大长度。最终,函数返回 result,即整个数组中摆动的个数。

3.实现代码
#include <iostream>
#include <vector>
using namespace std;

class Solution {
public:
    // wiggleMaxLength 函数用于计算摆动序列的最大长度
    int wiggleMaxLength(vector<int>& nums) {
        // 如果数组长度小于等于1,摆动序列的最大长度就是数组的长度
        if (nums.size() <= 1) return nums.size();

        int curDiff = 0; // 当前差异,用于存储当前元素与前一个元素的差值
        int preDiff = 0; // 前一个差异,用于存储上一次计算的当前差异
        int result = 1;  // 结果,用于记录摆动序列的最大长度,初始值为1(至少包含一个数)

        // 遍历数组,从第一个元素开始到倒数第二个元素
        for (int i = 0; i < nums.size() - 1; i++) {
            curDiff = nums[i + 1] - nums[i];// 计算当前元素与下一个元素的差值

            // 检查当前差异与前一个差异是否相反
            // 如果前一个差异非正(即等于0或负数)而当前差异为正,或者
            // 如果前一个差异非负(即等于0或正数)而当前差异为负,则表示发生了摆动
            if ((preDiff <= 0 && curDiff > 0) || (preDiff >= 0 && curDiff < 0)) {
                result++; // 如果发生了摆动,则摆动序列的长度增加
                preDiff = curDiff;// 更新 preDiff 为当前的 curDiff,用于下一次迭代的比较
            }
        }
        return result;// 返回摆动序列的最大长度
    }
};

//测试
int main()
{
    Solution p;
    vector<int> nums = { 1,7,4,9,2,5 };
    int result = p.wiggleMaxLength(nums);
    cout << "摆动序列的最大长度:" << result << endl;
    cout << endl;
    return 0;
}

 

 

三、最大子数组和

1.题目

Leetcode:第 53 题

给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。子数组是数组中的一个连续部分。

示例 1:

输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。

示例 2:

输入:nums = [1]
输出:1

示例 3:

输入:nums = [5,4,-1,7,8]
输出:23
2.解题思路

使用贪心算法解决最大子数组和问题。

(1)一般算法。
(2)贪心算法:在 maxSubArray 函数中,我们使用变量 result 来跟踪遍历过程中发现的最大子序和,初始值为 INT32_MIN。变量 count 用于计算从数组开始到当前索引的连续子数组的和。循环遍历数组 nums,我们将每个元素依次加到 count 上。如果 count 大于 result,则更新 result。如果 count 小于或等于 0,我们将 count 重置为 0,因为这表示当前的子数组和不会对后续子数组和产生贡献,我们从下一个元素开始计算新的子数组和。这种方法利用了贪心算法的思想,即在每一步选择中,都做出在当前状态下最好选择,从而希望导致结果是全局最优的。
最终,函数返回 result,即整个数组中连续子数组的最大和。

3.实现代码
#include <iostream>
#include <vector>
using namespace std;

// 一、最大子序和(暴力法)
class Solution1 {
public:
    // maxSubArray 函数用于计算(不连续)子数组的最大和
    int maxSubArray(vector<int>& nums) {
        int result = INT32_MIN; // 初始化结果为整数的最小值
        int count = 0; // 初始化计数器,用于计算子数组的和

        // 遍历数组,从每个元素开始
        for (int i = 0; i < nums.size(); i++) {
            // 这里应该从 i 开始一个新的子数组
            count = 0; // 重置计数器
            // 从当前位置 i 开始,遍历到数组末尾
            for (int j = i; j < nums.size(); j++) {
                count += nums[j];// 将当前元素 nums[j] 加到子数组的和中
                result = count > result ? count : result;// 更新结果为当前子数组的和和已知最大和中的较大者
            }
        }
        return result; // 返回计算得到的最大和
    }
};

// 二、最大子序和(贪心算法)
class Solution2 {
public:
    // maxSubArray 函数用于计算连续子数组的最大和
    int maxSubArray(vector<int>& nums) {
        int result = INT32_MIN; // 初始化结果为整数的最小值,用于记录最大子序和
        int count = 0; // 初始化计数器,用于计算当前子数组的和

        // 遍历数组中的每个元素
        for (int i = 0; i < nums.size(); i++) {
            count += nums[i];// 将当前元素的值加到 count 上,count 表示从索引 0 开始到当前索引的连续子数组的和
            // 如果当前子数组的和大于已知的最大子序和,则更新最大子序和
            if (count > result) {
                result = count;
            }
            // 如果当前子数组的和小于等于0,则重置 count 为 0,因为任何负数或零都会拉低后续子数组的和
            // 这相当于我们在遇到负数或零时,从下一个元素开始计算新的子数组和
            if (count <= 0) {
                count = 0;
            }
        }
        return result;// 返回计算得到的最大子序和
    }
};

//测试
int main()
{
    Solution2 p;
    vector<int> nums = { -2,1,-3,4,-1,2,1,-5,4 };
    int result = p.maxSubArray(nums);
    cout << "最大子序和:" << result << endl;
    cout << endl;
    return 0;
}

 

 

ps:以上皆是本人在探索算法旅途中的浅薄见解,诚挚地希望得到各位的宝贵意见与悉心指导,若有不足或谬误之处,还请多多指教。

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

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

相关文章

如何查看项目中使用的Qt版本

如何查看项目中使用的Qt版本 1.点击左下角电脑按钮查看Qt版本。 2.点击左侧栏项目按钮查看Qt版本。

Android开发——Fragment

Demo fragment_blank.xml <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_pare…

Windows系统远程桌面服务(RDP)的安全层和加密级别

1.【win10企业版/server2012】 1.服务器运行gpedit.msc&#xff0c;打开本地组策略&#xff0c;进入列表目录【计算机配置】-【管理模板】-【windows组件】-【远程桌面服务】-【远程桌面会话主机】-【安全】 2.双击“远程(RDP)连接要求使用指定的安全层”选项&#xff0c;配置…

Redis入门到通关之数据结构解析-RedisObject

文章目录 ☃️概述☃️源码 ☃️概述 RedisObject 是 Redis 中表示数据对象的结构体&#xff0c;它是 Redis 数据库中的基本数据类型的抽象。在 Redis 中&#xff0c;所有的数据都被存储为 RedisObject 类型的对象。 RedisObject 结构体定义如下&#xff08;简化版本&#xf…

linux负载均衡 和 系统负载分析笔记

1 负载均衡 1.1 计算负载 1.1.1 PELT算法简介 从Linux3.8内核以后进程的负载计算不仅考虑权重&#xff0c;⽽且跟踪每个调度实体的历史负载情况&#xff0c;该算法称为PELT(Per-entity Load Tracking) 《奔跑吧Linux内核》卷1&#xff1a;基础架构&#xff1b;P505 相关资料…

LeetCode216:组合总和Ⅲ

题目描述 找出所有相加之和为 n 的 k 个数的组合&#xff0c;且满足下列条件&#xff1a; 只使用数字1到9 每个数字 最多使用一次 返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次&#xff0c;组合可以以任何顺序返回。 解题思想 使用回溯算法 代码 class So…

Cubemx+RTL8201驱动

Cubemx 生产的驱动只能选择LAN8742&#xff0c;无法适配RTL8201&#xff0c;这篇文字就分享一下如何逐步修改lan8742的代码去适配。 一、地址问题 入口函数&#xff1a;int32_t LAN8742_Init(lan8742_Object_t *pObj) 主要是做PHY 地址检测&#xff0c;但是我们查阅RTL8201手…

2024中国国际中医药健康服务博览会(7月深圳中医药展)

聚焦中医国粹&#xff0c;助力健康中国 2024第五届中国国际中医药健康服务&#xff08;深圳&#xff09;博览会 暨粤港澳大湾区中医药高质量发展大会 邀请函 时间&#xff1a;2024年7月31日-8月2日 地址:深圳会展中心&#xff08;福田&#xff09; 支持单位&#xff…

WIFISKY 7层流控路由器 confirm.php RCE漏洞复现

0x01 产品简介 WIFISKY-7层流控路由器是一款可用于家庭或办公环境的无线路由器,具备流控功能以优化网络流量和提供更稳定的网络连接。该路由器采用了7层流控技术,能够依据网络数据包的内容进行智能管理,从而实现对网络流量的精细化控制和优化。这种技术可以提升网络的整体性…

MySQL-数据库基础

一、背景与基本使用 首先是登录方式&#xff0c;一般用 mysql -h 127.0.0.1 -P 3306 -u root -p mysql也是一种网络服务。 当然我们在本地登录时可以省去主机ip和端口号。 -h表示我们要登录mysql在哪个ip的主机上&#xff0c; -P表示端口号。 -u表示以谁的身份去登录。…

DDR的概念解读-提升速度的四把板斧

计算机以及手机系统性能的改善&#xff0c;不仅仅取决于cpu处理器主频的提升&#xff0c;还与cpu和内存之间的访问速度密切相关。 SDRAM: Synchronous Dynamic Random Access Memory,同步动态随机存取存储器&#xff0c;同步是指Memory工作需要同步时钟&#xff0c;内部命令的发…

最新热点:博弈+低碳!基于多主体主从博弈的区域综合能源系统低碳经济优化调度程序代码!

前言 随着能源需求上升及环境污染日益严重&#xff0c;安全高效、低碳清洁已成为能源发展的主流方向。在此背景下&#xff0c;统筹多能耦合、协同调度的区域综合能源系统已成为高效利用能源的重要形式。实现多能供应的安全性、经济性和灵活性的有效手段是优化RIES运行。因此&a…

vbox两步解决VirtualBox共享文件夹在Windows下的符号链接创建问题

默认情况下&#xff0c;VirtualBox 的共享文件夹特性在 Windows 下工作是有问题的&#xff0c;如果你运行一些需要符号连接&#xff08;Symlink&#xff09;的程序&#xff0c;比如默认设置的 yarn 或者 npm&#xff0c;由于 npm 包在安装之后会在 ./node_modules/.bin 创建在 …

B008-方法参数传递可变参数工具类

目录 方法参数传递可变参数冒泡排序Arrays工具类Arrays工具类常用方法 方法参数传递 /*** java中只有值传递* 基本数据类型 传递的是具体的值* 引用数据类型 传递的是地址值*/ public class _01_ParamPass {public static void main(String[] args) {// 调用方法 getSumge…

InFusion:通过从扩散先验学习深度补全来进行图像 3D 高斯修复

InFusion 以其图像条件模型超越了当前的方法&#xff0c;提供精确的深度修复并支持纹理定制和对象插入等高级应用程序。 github项目页面&#xff1a; Infusion Github 仓库&#xff1a;GitHub - ali-vilab/Infusion: Official implementations for paper: InFusion: Inpainti…

婚恋相亲软件优缺点揭秘:世纪佳缘、青藤之恋、二狗、伊对

曾经我也是个大龄单身狗&#xff0c;把市面上主流的相亲软件都装了一个遍&#xff0c;也充了不少会员&#xff0c;踩了不少坑&#xff0c;现把各个婚恋软件的优缺点梳理给大家。 二狗&#xff1a;原腾讯产品经理做的&#xff0c;号称高学历平台&#xff0c;用户质量堪称人类天花…

pycharm-git 配置(1)

1.安装git2.pycharm 中配置git 插件 弹出Git版本号&#xff0c;即配置成功。3.创建本地仓库 VCS->VCS operations->create repository->设置本地目录 左下角可以看到git本地仓库git可以看到push,commit。 4.配置远方仓库&#xff0c;此时确保git上是有这个项目…

Excel中将单元格格式改成文本后,为何要双击数字才会改变?

将大批量的数值型数字转换成文本型数字&#xff0c;当然不能一个一个的去双击做转换了。以下说说有哪个可以将数值型数字转换成文本型数字的方法。 一、转换方法 方法1.数据分列功能 选中数据后&#xff0c;点击数据选项卡&#xff0c;分列&#xff0c; 分列向导的第一步和…

上位机图像处理和嵌入式模块部署(智能硬件的介绍)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 目前&#xff0c;用上位机软件虽然可以部署项目&#xff0c;但是它本身有自己的缺点&#xff0c;那就是稳定性差、价格贵。稳定性这部分&#xff0…

jsoup接收429,404错误用来接收json格式

1.代码用例 try { // 拿到当前剩余余下的钱Document doc Jsoup.connect(url).header("Authorization", "Bearer " apiKey).header("Content-Type", "application/json").header("Connection", "keep-aliv…