【贪心算法题目练习】

1. 分发饼干

这道题目和我们之前讲到的田忌赛马的问题很相似,只不过这这里不需要劣等马去抵消掉优等马,直接上贪心策略:

先将两个数组排序。针对胃口较小的孩子,从小到大挑选饼干:

  • i. 如果当前饼干能满足,直接喂(最小的饼干都能满足,不要浪费大饼干) ;
  • ii. 如果当前饼干不能满足,放弃这个饼干,去检测下一个饼干(这个饼干连最小胃口的孩子都无法满足,更别提那些胃口大的孩子了)。

直接上代码:

class Solution {
public:
    int findContentChildren(vector<int>& g, vector<int>& s) {
        // 排序
        sort(g.begin(), g.end());
        sort(s.begin(), s.end());
        int i = 0;
        int j = 0;
        int ret = 0;
        while(j < s.size() && i < g.size())
        {
            if(s[j] >= g[i])
                ret++,j++,i++;
            else
                j++;   
        }
        return ret;
    }
};

2. 最优除法

我们可以看到这个题目的要求,它要求表达式的结果最大,那么在除数中我们可以尽量让分子大一点,让分母小一点即可,这就是我们的贪心策略:在最终的结果中,前两个数的位置是无法改变的,前两个数必定一个在分子,一个在分母,题目中说明每⼀个数的都是大于等于 2 的,所以此时可以用我们的贪心策略,为了让结果更大,我们应该尽可能的把剩下的数全都放在 「分子」上,直接上代码:

class Solution {
public:
    string optimalDivision(vector<int>& nums) {
        int n = nums.size();
        // 先处理两个边界情况
        if(n == 1) return to_string(nums[0]);
        if(n == 2) return to_string(nums[0]) + "/" + to_string(nums[1]);
        string ret = to_string(nums[0]) + "/(" + to_string(nums[1]);
        for(int i = 2; i < n; i++)
        {
            ret += "/" + to_string(nums[i]);
        }
        ret += ")";
        return ret;
    }
};

3. 跳跃游戏Ⅱ

动态规划解法:

  • a.状态表示:dp[i] 表示从0位置开始,到达i位置时候的最小跳跃次数
  • b.状态转移方程:对于dp[i],我们遍历0~i-1区间(用指针j表示),只要能够从j位置跳到i位置(nums[j]+j>=i) ,我们就用 dp[j]+ 1更新dp[i]里面的值,找到所有情况下的最小值即可。

类似层序遍历的过程:

  • 用类似层序遍历的过程,将第i次跳跃的「起始位置」和「结束位置」找出来,用这次跳跃的情况,更新出下一次跳跃的「起始位置」和「终止位置」这样「循环往复」,就能更新出到达n一1位置的最小跳跃步数

直接上代码:

class Solution {
public:
    int jump(vector<int>& nums) {
        int left = 0;
        int right = 0;
        int ret = 0;
        int maxpos = 0;
        while(true)
        {
            // 判断是否已经跳到最后一个位置
            if(nums.size() - 1 <= maxpos)
                return ret;
            // 遍历当层节点的最大步数
            for(int i = left; i <= right; i++)
            {
                maxpos = max(maxpos, nums[i] + i);
            }
            // 更新下一层的区间
            left = right + 1;
            right = maxpos;
            ret++;
        }
    }
};

4. 跳跃游戏

这个题目和上面的题目思路基本上差不多,但是上一个题目的明显说了一定会到达最后一个下标位置,而我们这道题目是判断能否到达最后一个下标位置,基于上一个题目我们仅需修改⼀下返回值即可,直接上代码啦!!!

class Solution {
public:
    bool canJump(vector<int>& nums) {
        int left = 0;
        int right = 0;
        int maxpos = 0;
        int n = nums.size();
        while(left <= right)// 以防跳不到 n - 1 的位置
        {
            // 判断是否已经能跳到最后⼀个位置
            if(maxpos >= n - 1)
                return true; 
            for(int i = left; i <= right; i++)
            {
                maxpos = max(maxpos, nums[i] + i);
            }
            left = right + 1;
            right = maxpos;
        }
        return false;
    }
};

5. 加油站

暴力解法:

  • a. 依次枚举所有的起点;
  • b. 从起点开始,模拟⼀遍加油的流程
  • c. 如果油的剩余量小于0,代表无论怎样,你都不可能绕环路行驶一周,否则可以。
class Solution
{
public:
	int canCompleteCircuit(vector<int>& gas, vector<int>& cost)
	{
		int n = gas.size();
		for (int i = 0; i < n; i++) // 依次枚举所有的起点
		{
            int rest = 0; // 标记⼀下净收益
            for (int step = 0; step < n; step++) // 枚举向后⾛的步数
            {
                int index = (i + step) % n; // 求出⾛step步之后的下标

                rest = rest + gas[index] - cost[index];
                if (rest < 0) break;
            }
            if (rest >= 0) return i;
		}
		return -1;
	}
};

但是此时会超出时间限制,复杂度太高,我们可以优化一下哈,我们发现,当从 i 位置出发,走了 step 步之后,如果失败了。那么 [i, i + step] 这个区间内任意⼀个位置作为起点,都不可能环绕⼀圈。

因此我们枚举的下⼀个起点,应该是 i + step + 1。

class Solution
{
public:
	int canCompleteCircuit(vector<int>& gas, vector<int>& cost)
	{
		int n = gas.size();
		for (int i = 0; i < n; i++) // 依次枚举所有的起点
		{
            int rest = 0; // 标记⼀下净收益
            int step = 0;
            for (; step < n; step++) // 枚举向后⾛的步数
            {
                int index = (i + step) % n; // 求出⾛step步之后的下标

                rest = rest + gas[index] - cost[index];
                if (rest < 0) break;
            }
            if (rest >= 0) return i;
            i = i + step; // 优化
		}
		return -1;
	}
};

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【CPP】栈简介及简化模拟实现

CPP栈和队列简单模拟实现 目录 1. 栈的简介2. 栈简化模拟实现3. 栈练习题 1. 栈的简介 栈 是一种 特殊的线性表&#xff0c;具有数据 先进后出 特点。 具体参考&#xff1a;【数据结构】栈 CPP库参考文档&#xff1a;stl_stack 注意&#xff1a; 1.stack本身 不支持迭代器操…

C++之构造函数总结

1、构造函数定义 在C中&#xff0c;构造函数是一种特殊的成员函数&#xff0c;它在创建一个类的对象时自动被调用。构造函数的主要目的是初始化类对象的成员变量&#xff0c;为对象分配资源&#xff0c;以及执行任何其他必要的初始化任务。 构造函数具有以下特点&#xff1a; …

WinApp自动化测试之辅助工具介绍

前篇文章中&#xff0c;我们简单介绍了部分WinApp自动化测试脚本常规操作&#xff0c;今天我们来讲剩余的部分。 文件批量上传 文件批量上传和文件单个上传原理是相同的&#xff0c;单个上传直接传入文件路径即可&#xff0c;批量上传需要进入批量上传的文件所在目录&#xf…

python-双胞胎字符串

[问题描述]&#xff1a;给定两个字符串s和t&#xff0c;每次可以任意交换s的奇数位和偶数位的字符&#xff0c;即奇数位的字符可以与任意其它奇数位的字符交换&#xff0c;偶数位的字符同样也可以与任意偶数位的字符的字符交换&#xff0c;问能否在有限的次数的交换下使s变为t?…

0基础学习Elasticsearch-Quick start

文章目录 1 背景2 前言3 快速部署ES4 快速部署Kibana5 发送请求给ES5.1 打开Kibana控制台5.2 通过REST API发送请求5.3 通过curl发送请求5.4 添加数据5.4.1 添加单个document5.4.2 添加多个document 5.5 搜索数据5.5.1 搜索所有documents5.5.2 match查询 6 总结 1 背景 因电商项…

【算法】模拟算法——外观数组(medium)

题解&#xff1a;模拟算法——外观数组(medium) 目录 1.题目2.题解3.参考代码4.总结 1.题目 题目链接&#xff1a;LINK 2.题解 首先应该理解题意&#xff1a; 就是开始给你一个字符串&#xff0c;然后你对其进行描述。 描述规则是&#xff1a;连续的数字为一组&#xff0c;…

大学生社团活动平台系统基于springboot+vue的社团管理系统java项目sprignboot项目

文章目录 大学生社团活动平台一、项目介绍二、部分功能截图三、部分代码展示四、底部获取项目源码&#xff08;9.9&#xffe5;带走&#xff09; 大学生社团活动平台 一、项目介绍 基于springbootvue的前后端分离大学生社团活动平台 系统角色 : 学生、社长、管理员 1、学生…

自学 Java 怎么入门?

关于自学 Java 如何入门这一重要课题&#xff0c;在此为大家进行详细阐述。 在此之前&#xff0c;如果大家有兴趣的话&#xff0c;可以看看我自己精心整理的嵌入式入门资料&#xff0c;这些资料将全部免费送给大家。其中包含了编程教学内容、详细的视频讲解、实用的数据库资料…

Java项目:92 基于SSM的办公管理系统

作者主页&#xff1a;舒克日记 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 基于SSM的办公管理系统 1、项目介绍 基于SSM的办公管理系统主要是对于办公用品的申领进行管理&#xff0c;系统分为三种角色&#xff0c;超级管理员、企业 职…

自然语言处理基础知识入门(六) GPT模型详解

GPT 前言一、GPT模型1.1 为什么采用Decoder模块&#xff1f;1.2 为什么不使用Encoder模块&#xff1f; 二、 模型训练2.1 预训练阶段2.2 半监督微调 总结 前言 在之前的章节中&#xff0c;深入探究了预训练ELMo模型的架构与实现原理。通过采用双向LSTM架构在大规模文本数据上进…

C++匿名对象

struct&#xff1a;结构体内默认访问权限&#xff1a;public公共->哪里都能用 class&#xff1a;结构体内默认访问权限&#xff1a;private私有->只能在类里使用 简单版本&#xff1a; class SV { public:SV(int dt 520):_data1(dt){};int R_num(){return _data1;}priv…

易语言本地IP一键切换程序(附带源码)

易语言本地IP一键切换程序 效果图部分源码源码领取下期更新预报 效果图 部分源码 .判断开始 (单选框1.选中 &#xff1d; 真)标签5.标题 &#xff1d; #换行符 &#xff0b; “正在切换IP.”.如果真 (运行 (“netsh interface ip set address ” &#xff0b; #引号 &#xff…

yxc图示“链式前向星”核心操作

【知识点&#xff1a;链式前向星】 ● 大佬 yxc 指出“链式前向星”就是“多单链表”&#xff0c;并基于“头插法”给出了所涉及到的 e[]、ne[]、h[] 等数组的独特解释&#xff0c;更易理解。其中&#xff1a;h[a]&#xff1a;存储单链表表头结点 a 的编号e[idx]&#xff1a;存…

vue-el-steps 使用1(上一步、下一步)

vue代码 <template> <div class"app-container"> <el-steps :active"active" finish-status"success" simple style"margin-top: 20px"> <el-step title"选择分类"></el-step> <el-step t…

Linux实验报告(一)——Linux系统安装与简单配置

目录 一、实验名称&#xff1a; 二、仪器、设备&#xff1a; 三、参考资料&#xff1a; 四、实验目的&#xff1a; 五、实验内容&#xff08;步骤&#xff09;&#xff1a; 六、实验数据&#xff08;程序&#xff09;记录&#xff1a; 七、实验结果分析&#xff1a; 八、…

Keras深度学习框架实战(2):估计模型训练所需的样本量

1、模型训练样本量评估概述 1.1 样本量评估的意义 预估模型需要的样本量对于机器学习项目的成功至关重要&#xff0c;以下是几个主要原因&#xff1a; 防止过拟合与欠拟合&#xff1a; 过拟合&#xff1a;当模型在训练数据上表现极好&#xff0c;但在未见过的测试数据上表现糟…

低代码平台:教育机构数字化转型的技术新引擎

在数字化浪潮汹涌而来的今天&#xff0c;教育行业正迎来前所未有的变革。随着技术的不断进步和教育理念的更新&#xff0c;越来越多的教育机构开始意识到数字化转型的重要性。而在这场转型的浪潮中&#xff0c;低代码平台以其独特的优势&#xff0c;正成为教育机构实现数字化转…

2024年Kubernetes管理的发展趋势及预测

Kubernetes管理的概念 Kubernetes管理是指用于监督使用Kubernetes的跨机器集群的容器化应用程序的部署、扩展和操作的过程和工具。这个编排平台自动化了部署、管理和扩展容器化应用程序的许多方面&#xff0c;但它也引入了配置、网络、安全性和资源管理方面的复杂性。 有效的K…

jmeter常用的断言

包括&#xff08;Contains&#xff09;&#xff1a;响应内容包括需要匹配的内容即代表响应成功&#xff0c;支持正则表达式 匹配&#xff08;Matches&#xff09;&#xff1a;响应内容要完全匹配需要匹配的内容即代表响应成功&#xff0c;大小写不敏感&#xff0c;支持正则表达…

keepalived安装文档

目录 1、安装环境 2、安装keepalived 2.1 上传keepalived安装文件 2.2 解压 2.3 安装keepalived 2.4 加入开机启动&#xff1a; 2.5 配置日志文件 2.6 打开防火墙的通讯地址 1、安装环境 su - root yum -y install kernel-devel* yum -y install openssl-* yum -y …